2011-03-25 11 views
6

Estoy tratando de crear una lista personalizada que tendrá casillas que le permitan seleccionar varios elementos de la lista.Vista de lista personalizada con el problema de casilla de verificación

La lista con las casillas de verificación se muestra bien, pero si marque una casilla de verificación y luego desplace otros elementos más abajo, la lista también se marcará.

Es básicamente el mismo problema que here

entiendo que tiene algo que ver con la forma androide recicla la vista, pero no puedo ver cómo solucionar este problema! ¿¿¿Puede alguien ayudarme???

Gracias - Mike

Respuesta

5

Se necesita una estructura de datos para realizar un seguimiento de los cuales se comprueban filas. Esto podría ser tan simple como bool[] checked.

En su getView, asegúrese de establecer el estado de la casilla de verificación en el contenido de checked[position]. También debe set an OnCheckedChangedListener en sus casillas de verificación en getView para que actualicen sus datos con .

Sí, las filas en un ListView se reciclan, así que asegúrese de completar todos los datos apropiados para una fila antes de salir de getView.

+1

Excelentes funciona como un encanto! ¡No sabía que el método getView se llama cada vez que se desplaza! ¡Pensé que toda la lista se inicializa y luego nunca se llama al método getView! – mixkat

+0

Pensé que había solucionado esto, pero estaba equivocado.Es extraño porque en el setOnCheckedChangeListener debo tenerlo al revés para poder trabajar, es decir, si se comprueba, entonces establezca el campo apropiado de la matriz en falso y verdadero de lo contrario. Pero cuando tengo que verificar qué casillas están marcadas, todo está en mal estado. Nota: si configuro correctamente, es decir, establezco el campo de matriz en verdadero cuando la casilla está marcada y luego pierde todo si me desplazo hacia abajo y hacia atrás otra vez. Cualquier idea ¿Por qué está pasando esto? – mixkat

+0

¿Estás seguro de que llamas a 'setChecked' incluso para las vistas recicladas? En otras palabras, 'if (convertView == null) {/ * inflate view * /}/* llena las vistas independientemente de si está reciclado/no reciclado fuera de la instrucción if * /' –

0

Crea un ArrayList<Integer>. agregue un OnCheckChangedListener a su casilla de verificación. Dentro del método cambiado, agregue o elimine la vista de lista position al ArrayList<Integer>.

en su método getView, compruebe si el ArrayList<Integer> contiene la vista de lista actual position. si contiene la posición, establezca checked en verdadero, de lo contrario falso.

cada vez que haga clic en una casilla de verificación, agregue o elimine Integer del ArrayList.

2

Puede intentar la implementación de OnClickListener para la casilla de verificación en lugar de OnCheckChangedListener. Funcionó para mí

0

Comprobar el código de abajo -

public View getView(int position, View convertView, ViewGroup parent){ 
      View view = convertView; 
      ViewHolder holder = new ViewHolder(); 

      if(view == null){ 

       view = inflater.inflate(R.layout.list_callcycle_blue, null);     
       holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container); 
       holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc); 
       holder.cb = (CheckBox) view.findViewById(R.id.cb_store); 

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

      final Object data = getItem(position); 
      holder.lblLabel.setText(data.getDescription()); 

      holder.cb.setTag(position); 
      holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

        int position = (Integer) buttonView.getTag(); 
        objects.get(position).setChecked(buttonView.isChecked()); 
       } 
      }); 
      holder.cb.setChecked(isChecked(position)); 

      return view; 
     } 

Siempre tenga en mente, el cambio de uso holder.cb.setOnCheckedChangeListener()es decir cualquier oyente antes de que los datos de ajuste, en nuestro caso es holder.cb.setChecked()

Motivo: Cuando scroll, listview reciclará las vistas, de modo que si setchecked se usa antes que los oyentes, elegirá los valores en función del viejo oyente. Y si lo ponemos después oyente, entonces tomará últimos valores

parte editada A continuación se mostrará cómo parte isChecked() y setChecked() métodos utilizados para recuperar los datos revisados ​​

/* 
* This function is in your Custom Adapter Class 
*/ 
private boolean isChecked(int position){ 
    return object(position).isChecked(); 
} 


/** 
* Getter Setter Class/Data Model Class that defines your object 
*/ 
private class MyObject{ 
    private boolean isChecked; 
    private String a, b, c, orWhateverYourObjectNeeds; 

    public void setChecked(boolean isChecked){ 
     this.isChecked = isChecked; 
    } 

    public boolean isChecked(){ 
     return isChecked 
    } 
} 
+0

Hola Jimit Patel, ¿puedes explicar cómo se obtienen "objetos" y "isChecked (position)" de tu código arriba? Gracias –

+0

lo he editado hace mucho tiempo. Olvidé comunicarme, lo siento –

Cuestiones relacionadas