Pregunta sobre android, android-listview – Seleccione varios elementos de la vista de lista y cambie el color del elemento seleccionado solamente

6

Quiero hacer una vista en la que pueda seleccionar varios elementos de la vista de lista y también de lado a lado estoy cambiando el color del elemento de la lista seleccionada y guardando ese elemento en mi arraylist ... Mi lista se muestra a continuación como:

Pero cuando solía desplazarme ... Me está mostrando 1 elemento más seleccionado, aunque no lo estoy seleccionando como:

Pero quiero que solo el color del elemento de la lista cambie donde haré clic ...

Estoy usando el código como:

<code>     private class ItemsAdapter extends ArrayAdapter<String> {
 List<String> items;
  Context context;
  private LayoutInflater inflater;
  public ItemsAdapter(Context context, List<String> part_array_list) {
     super( context, R.layout.part_list, R.id.label,part_array_list );

     inflater = LayoutInflater.from(context) ;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      TextView textView ; 
    String item = (String) this.getItem( position ); 

      if ( convertView == null ) {
        convertView = inflater.inflate(R.layout.part_list, null);

        // Find the child views.
        textView = (TextView) convertView.findViewById( R.id.label );


        // Optimization: Tag the row with it's child views, so we don't have to 
        // call findViewById() later when we reuse the row.
        convertView.setTag( new ListViewHolder(textView) );


      }
      // Reuse existing row view
      else {
        // Because we use a ViewHolder, we avoid having to call findViewById().
        ListViewHolder viewHolder = (ListViewHolder) convertView.getTag();

        textView = viewHolder.getTextView() ;

      }


      textView.setText( part_array_list.get(position) );      

      return convertView;


      }
      }
        /** Holds child views for one row. */
           private class ListViewHolder {

 private TextView textView ;
 public ListViewHolder() {}
 public ListViewHolder( TextView textView ) {

   this.textView = textView ;
 }

 public TextView getTextView() {
   return textView;
 }
 public void setTextView(TextView textView) {
   this.textView = textView;
 }    
</code>

}

y en el método OnCreate (),

<code>         final ArrayAdapter<String> part_list_adapter=new ItemsAdapter(AssetSearch.this, part_array_list);
        //PartNumber_List.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    PartNumber_List.setAdapter(part_list_adapter);

    PartNumber_List.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position,
            long id) {
         ListViewHolder viewHolder = (ListViewHolder) v.getTag();
         viewHolder.getTextView().setBackgroundColor(R.color.result_image_border);

        String item=(String) part_list_adapter.getItem((int) id);
        });
</code>
Esto se debe a que en la lista de Android se recicla cuando se desplaza por la lista. Sujit

Tu respuesta

7   la respuesta
0

La solución (idea) deJason Robinson Es bueno, pero hay un error! No puede eliminar el elemento de ArrayList por su valor !!!
El método ArrayList.remove (int) toma el índice del elemento como parámetro!
Si quieres usar unArrayList<<code>Integer</code>>, necesitas encontrar el ítem de índice que deseas eliminar. Por ejemplo:

<code>private int getIndex(int value) {
    int index = -1;

    for(int i=0; i<selectedIds.size(); i++) {
        if(selectedIds.get(i)==value) {
            index = i;
            break;
        }
    }

    return index;
}
</code>

O usar metodoArrayList.indexOf(Object) para obtener el índice.

Y ahora, cómo obtener referencia a su adaptador desde FragmenList o ListActivity. Simplemente usa la variable de clase:

<code>public class SimpleFragment extends ListFragment {
    private MyCustomAdapter mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mAdapter = new MyCustomAdapter(getActivity(), R.layout.row_layout);
        setListAdapter(mAdapter);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // now you have an access to your adapter through class variable mAdapter
    }
}
</code>
Otra solución al primer problema que mencionó es usar un HashSet en lugar de un ArrayList. HashSet.remove () toma el objeto en cuestión en lugar de un índice:developer.android.com/reference/java/util/… Jabari
0

<code>if(selectedIds.contains(pos) {
         selectedIds.remove(pos); -> **selectedIds.remove(selectedIds.indexOf(pos));**
     }
     else {
         selectedIds.add(pos);
     }
</code>
3

También me he encontrado con este problema, y ​​descubrí que es porque recicla vistas. Si recuerdo la configuración correcta, esto elimina el reciclaje y soluciona el problema, pero no es la mejor opción aquí.

<code>@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
</code>
No, no está funcionando ... Kanika
No, no está funcionando ... ¿Dónde poner este método? Kanika
Agregue también esto: @Override public int getViewTypeCount () {return 1; } Niko
Gracias @Niko por tu apoyo .. Tengo la solución :) Kanika
Anula este método para la clase de adaptador. Niko
1

Independientemente de lo que intente hacer con ConvertView en el escucha de ItemClick, se reflejará en alguna otra clase.

<code>public View getView(final int position, View convertView, ViewGroup parent) {
         System.gc();
         final ViewHolder holder;

         if (convertView == null) {
             convertView = mInflater.inflate(R.layout.albumlist, null);
             holder = new ViewHolder();
             holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails);

           ,  convertView.setTag(holder);
         }
         else {
             holder = (ViewHolder) convertView.getTag();
         }


         holder.albumName.setText(albumData[position][0]);

         holder.albumName.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 holder.albumName.setBackgroundColor(R.color.black);


             }});

         return convertView;
 }

     class ViewHolder {

         TextView albumName;


     }
</code>

muestra o / p

10

El problema aquí es que está configurando el color de fondo para la vista, luego, cuando se desplaza, termina reutilizando esa vista debido al uso deconvertView. Esto es exactamente lo que deberías estar haciendo, así que buen trabajo allí.

Pero, por supuesto, eso significa que los elementos de la lista se seleccionan cuando no deberían serlo. Para arreglar esto, tugetView() El método necesita restablecer el color de fondo a su valor predeterminado. No sé cuál era el color originalmente, pero asumiré que era transparente. Así que pondrías:

<code>textView.setBackgroundColor(android.R.color.transparent);
</code>

Así que ahora está configurando el color de fondo a su valor predeterminado, pero si se aleja del elemento seleccionado y luego vuelve a él, tendrá un fondo transparente en lugar del fondo seleccionado. Para resolver esto, pon unArrayList deInteger Valores dentro de su clase de adaptador. Cuando se hace clic en un elemento yonItemClick() se activa, agregue la posición del elemento a eseArrayList. Por ejemplo, digamos que tienes:

<code>public ArrayList<Integer> selectedIds = new ArrayList<Integer>();
</code>

en su clase de adaptador Entonces tuonItemClick El método se vería así:

<code>@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

     ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds;
     Integer pos = new Integer(position);
     if(selectedIds.contains(pos) {
         selectedIds.remove(pos);
     }
     else {
         selectedIds.add(pos);
     }

     parent.notifyDataChanged();
}
</code>

Así que, finalmente, en tugetView() Método, agregue esta línea:

<code>textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
</code>
@Kanika Puse ArrayList en el adaptador e intenté acceder a él desde onItemClick en la clase de actividad. Pero sigue mostrando "No se puede emitir desde AdapterView <captura # 1-de?> MyAdapter". ¡Por favor ayuda! user3014926
@Kanika Oye, también obtuve el mismo error que "No se puede emitir desde AdapterView <captura # 1-de?> A" ... y no puedo entenderlo. Así que, por favor, dime cómo tienes la solución ... por favor ayuda ... :( Kinjal Shah
Funciona muy bien para mí! user2999943
Hola, muchas gracias por su respuesta, pero cuando agrego ArrayList <Integer> selectedIds = new ArrayList <Integer> (); en mi clase de adaptador, luego en onlistItemClick, no está tomando ((ItemsAdapter) parent) .selectedIds; Me está dando un error aquí y no extrae la variable selectedIds de la clase de adaptador :( ayuda por favor qué hacer Kanika
1

Mantenga un registro de los elementos seleccionados en el listView en la actividad. En el getView del adaptador, compruebe si la posición es igual a la posición seleccionada en la vista de lista y setBackgroundColor para la vista allí. Esto funcionará.

0

la lista de la lista y marque este indicador para determinar el tiempo en el que se hizo clic o no en el método getView () del adaptador.

los pls ayudan a implementar esto ... Estoy atascado en este problema de ayer y no obtuve ninguna solución todavía :( Kanika

Preguntas relacionadas