2011-05-23 30 views
31

Tengo un problema con la vista de lista que elemento de la lista contiene una casilla de verificación. ¡Cuando miro una caja y una lista de desplazamiento, la casilla de verificación en algún momento se cambia la llamada automática oncheckedchange y el valor de la casilla de verificación!casilla de verificación llamada automática enCheckedChange cuando listview scroll?

O, cuando mi lista tiene más de 9 o 10 artículo, a continuación, cuando llegué al punto 1, el punto 8 o 9 se comprueba ???

Alguien me puede decir qué puedo solucionar este error?

¡Gracias de antemano!

list_item.xml

<ImageView 
    android:layout_alignParentLeft="true" 
    android:layout_width="36dip" 
    android:layout_height="36dip" 
    android:layout_centerVertical="true" 
    android:scaleType="fitCenter" 
    android:id="@+id/image_view" 
    android:src="@drawable/icon" /> 

<TextView android:layout_toRightOf="@id/image_view" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:paddingLeft="5dip" 
    android:id="@+id/text_view" 
    android:lines="1" 
    android:textSize="20sp" 
    android:textColor="@color/white" /> 

<TextView android:layout_toRightOf="@id/image_view" 
    android:layout_below="@id/text_view" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:paddingLeft="5dip" 
    android:id="@+id/text_view2" 
    android:textSize="14sp" 
    android:lines="1" 
    android:textColor="@color/white" />   

y aquí es una vista del adaptador:

public View getView(int position, View convertView, ViewGroup parent) { 
     Log.e(TAG, "getView"); 
     ViewHolder mViewHolder; 
     if (convertView == null) { 
      Log.e(TAG, "Inflater is inflating..."); 
      convertView = mInflater.inflate(R.layout.custom_list_app, null); 
      mViewHolder = new ViewHolder(); 
      mViewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox); 
      mViewHolder.remove = convertView.findViewById(R.id.music_info); 
      convertView.setTag(mViewHolder); 
     } else { 
      mViewHolder = (ViewHolder) convertView.getTag(); 
      Log.e(TAG, "Position: " + position + " CheckBox: " + mViewHolder.checkbox.isChecked()); 
     } 
     mViewHolder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton cb, boolean flag) { 
       // TODO Auto-generated method stub 
       if (flag) { 
        Log.d(TAG, "Checkbox checked"); 
       } else { 
        Log.d(TAG, "Checkbox un-checked"); 
       } 
      } 
     }); 


     return convertView; 
    } 

Respuesta

71

El ListView recicla las clases de vista: deberá establecer explícitamente si el CheckBox está o no marcado en la clase getView. Así que añadir un cheque como

/** 
* Ensure no other setOnCheckedChangeListener is attached before you manually 
* change its state. 
*/ 
mViewHolder.checkbox.setOnCheckedChangeListener(null); 
if(shouldBeChecked) mViewHolder.checkbox.setChecked(true); 
else mViewHolder.checkbox.setChecked(false); 

antes de llamar setOnCheckedChangeListener.

+0

Creo que la solución es la siguiente. Utilizo una matriz para almacenar la posición cuando la casilla de verificación está marcada y verifico dónde está marcada la posición antes de llamar a setOnCheckedChangeListener. ¡Pero cuando cambio la lista (no marca) la posición donde está marcada ha cambiado! No entiendo por qué ocurre – khaintt

+0

Bueno, SIEMPRE deberías llamar a 'setOnCheckedChangeListener', pero deberías usar el argumento' position' para 'getView' para decir si la casilla de verificación debe o no marcarse y cambiarla apropiadamente CADA VEZ' getView 'se llama. – Femi

+3

Déjeme repetir eso: DEBE invocar 'setChecked (true)' o 'setChecked (false)' CADA vez que se llame a 'getView' si está anulando' getView'. – Femi

4
holder.cBox.setOnCheckedChangeListener(null); 
holder.cBox.setChecked(list.get(position).isChecked()); 
holder.tvName.setText(item.getName()); 

holder.cBox.setOnCheckedChangeListener(new OnCheckedChangeListener() 
{ 
    @Override 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
    { 
     if (isChecked) 
     { 
      list.get(position).setChecked(true); 
     } 
     else 
     { 
      list.get(position).setChecked(false); 
     } 
    } 
}); 

En la lista, el elemento tiene un atributo para establecer si el elemento está marcado o no. Usted puede usar esto para fijarle elemento si se verificó, y primero se debe configurar el

cBox.setOnCheckedChangeListener(null); 
cBox.setChecked(list.get(position).isChecked()); 

A continuación, establezca el verdadero new OnCheckedChangeListener()

espero que mi respuesta es útil para ti y los que mirar en esta página o tienen problemas para lidiar con listviews que tienen casillas de verificación de elementos.

0

no estoy seguro de si se trata de una manera ordenada. Pero el siguiente código resolvió mi problema. Incluso en el siguiente código, se llamaba a setOnCheckChangeListener() (se leía falsamente activado) al desplazarse por la lista. La tarea era mantener una lista de elementos que el usuario había seleccionado. Entonces, cuando hay un disparador, primero remito mi lista y solo agrego un ítem si no estaba ya presente en la lista, de lo contrario, ignoro la devolución de llamada.

@Override 
public View getView(final int position, View convertView, final ViewGroup parent) { 


    MenuViewHolder menuViewHolder = null; 
    MenuView item = getItem(position); 


    LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 

    convertView = inflater.inflate(R.layout.food_menu_list_layout, null); 

    TextView textView = ((TextView) convertView.findViewById(R.id.menu_item_entry)); 
    TextView price = (TextView) convertView.findViewById(R.id.price); 
    CheckBox ordered = (CheckBox) convertView.findViewById(R.id.checkBox); 

    menuViewHolder = new MenuViewHolder(textView, price, ordered); 

    menuViewHolder.dishName.setText(menuViewList.get(position).getItemname()); 
    menuViewHolder.price.setText("$" + menuViewList.get(position).getPrice()); 
    menuViewHolder.ordered.setChecked(menuViewList.get(position).isSelected()); 

    menuViewHolder.ordered.setOnCheckedChangeListener(null); 


    menuViewHolder.ordered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

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

      MenuView checkedItem = menuViewList.get(position); 
      if (buttonView.isChecked()) { 

       //add item only if not already added 
       if (!checkedItem.isSelected()) { 
        MainActivity.menuViews.add(checkedItem); 
        checkedItem.setSelected(buttonView.isChecked()); 
       }  


      } else { 

       //remove only if already added 
       if (checkedItem.isSelected()){ 
        MainActivity.menuViews.remove(checkedItem); 
        checkedItem.setSelected(buttonView.isChecked()); 
       }      
      } 

      ((MainActivity) context).displayCurrentSelectionAmt(); 
     } 
    }); 


return convertView; 

} 
0

La mayoría de estos son demasiado complicados (pero funcionan). Todo lo que intenta hacer es evitar que el evento .setChecked se active si la vista se está cargando y configurando el estado verificado. Por lo tanto, establezca una variable de clase local isLoading, establézcalo en true al comienzo de getView y establézcalo en false al final de getView. Luego, en el detector de clics, verificar isLoading

boolean isLoading; 
public View getView(int position, View convertView, ViewGroup parent){ 
    isLoading = true; 

    ...do your initialization here 

    isLoading = false; 
    return convertView; 
} 
checkview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton pckView, boolean pisChecked) { 
      if(! isLoading) { 
       ...do your things when the check is actually clicked 
      } 
     } 
    }); 
0

El OnClickListener se trabajó para mí con el mismo problema y puedo enviar un documento a otra actividad

holder.cks.setOnClickListener (nueva vista.OnClickListener() {

  @Override 
      public void onClick(View v) { 
       final boolean isChecked = holder.cks.isChecked(); 
       if (isChecked) { 
        System.out.println(position + "Checked"); 
        holder.cks.setChecked(true); 
        positionArray.set(position, true); 
        DATA2="1"; 



       } else { 
        System.out.println(position + "unChecked"); 
        holder.cks.setChecked(false); 
        positionArray.set(position, false); 

        DATA2 = "0"; 

       } 
       DATA1=String.valueOf(position+1); 

       DATA3=map.get(COL5); 
       DATA4=map.get(COL6); 
       DATA5=map.get(COL7); 



       Intent intent = new Intent(activity, updatelicaldata.class); 
       intent.putExtra("message1", DATA1); 
       intent.putExtra("message2", DATA2); 
       intent.putExtra("message3", DATA3); 
       intent.putExtra("message4", DATA4); 
       intent.putExtra("message5", DATA5); 
       System.out.println("ACTIVITY IS START"); 

       activity.startActivity(intent); 

      } 
      }); 
Cuestiones relacionadas