6

enter image description hereкак добавить слушатель для флажков в целях адаптера, Android, ArrayAdapter, onCheckedChanged, OnCheckedChangeListener

У меня есть ListView, что путем к ArrayAdapter заполняются мелкими видами XML подразделов. каждый маленький вид имеет только две вещи внутри, флажок и строковый ярлык рядом с ним.

Я хочу установить прослушиватель onCheckedChanged, чтобы зафиксировать событие, когда пользователь проверяет или снимает флажки.

, например слушатель показано здесь:

listView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

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

Toast.makeText(this, "box has been checked", Toast.LENGTH_SHORT).show(); 

} 

}

где нужно поместить код слушателя? и как мне настроить его?

код ArrayAdapter:

public class MobileArrayAdapter extends ArrayAdapter<CheckBoxInfo>{ 
    CheckBoxInfo[] objects; 
    Context context; 
    int textViewResourceId; 

    public MobileArrayAdapter(Context context, int textViewResourceId, 
     CheckBoxInfo[] objects) { 
     super(context, textViewResourceId, objects); 
     this.context = context; 
     this.textViewResourceId = textViewResourceId; 
     this.objects = objects; 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row_layout_view = convertView; 


      if ((row_layout_view == null)){ 


       LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       row_layout_view = inflater.inflate(R.layout.row_layout, null); 
      } 

      //CheckBoxInfo item = objects.get(position); // for arrayList 
      CheckBoxInfo item = objects[position]; 

      if(item != null){ 

      TextView textView = (TextView) row_layout_view.findViewById(R.id.textView1); 
      CheckBox checkBox = (CheckBox) row_layout_view.findViewById(R.id.checkBox1); 

      if(item !=null){ 
      textView.setText(item.checkBoxName); 
      checkBox.setChecked(item.checkBoxState); 
       } 
      } 
      return row_layout_view; 
    } 


} 

ответ

29

Не используйте пример listView.setOnCheckedChangeListener или onCheckedChanged кода.

Прежде всего, для CheckBox, вы должны использовать setOnClickListener() вместо setOnCheckedChangeListener(). Вы можете получить проверенное состояние внутри функции onClick().

Во-вторых, разместите setOnClickListener() внутри функции getView() функции списка адаптера.

Пример:

checkBox.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View arg0) { 
     final boolean isChecked = checkBox.isChecked(); 
     // Do something here. 
    } 
}); 
+3

Я не думаю, что это работает, потому просмотров переработки ListView. Когда вы прокручиваете вниз, и выбранный convertView перерабатывается, проверенная строка становится неконтролируемой. Как вам обойти это? –

+4

Это правильное поведение. Когда View снова используется, все его дочерние объекты имеют характеристики бессмысленного представления, которое было переработано. Поэтому вы должны обновлять все представления и их атрибуты в 'getView()' каждый раз. Сюда входит установка значения CheckBox, а также его 'OnClickListener'. В общем, держите слушателя и добавьте 'checkBox.setChecked()', чтобы установить его на ожидаемое значение, в случае, если переработанное (или новое) представление имеет другую настройку. –

1

Спасибо David! в отношении комментария HukeLau_DABA, я решил его, обновив объект просмотра списка с помощью значения CheckBox внутри OnClickListener(). В моем случае у меня есть список мест, как можно видеть в следующем коде:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() { 

     //please note that objPlace, position and holder must be declared 
     //as final inside the getView() function scope. 
      @Override 
      public void onClick(View arg0) { 
       final boolean isChecked = holder.placeCheckBox.isChecked(); 
       if (isChecked){ 
        objPlace.setItemChecked("yes"); 
       }else{ 
        objPlace.setItemChecked("no"); 
       } 

       placesList.set(position,objPlace); // updating the list with the updated object 

      } 
     }); 
1

не относятся к «holder.placeCheckBox» в вашем onClickListener, вам следует обратиться, чтобы посмотреть, который передается по OnClick и приведение его в CheckBox так код должен выглядеть следующим образом:

holder.placeCheckBox.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 
      boolean isChecked = ((CheckBox)arg0).isChecked(); 
      if (isChecked){ 
       objPlace.setItemChecked("yes"); 
      }else{ 
       objPlace.setItemChecked("no"); 
      } 

      placesList.set(position,objPlace); // updating the list with the updated object 

     } 
    }); 
0

Вы можете попробовать это:

holder.placeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
     Log.d(TAG, "onCheckedChanged: " + holder.placeCheckBox.getText() + " " + (b ? "selected":"deselected")); 
    } 
}); 
Смежные вопросы