Странное поведение ListView с CheckBox

У меня есть CheckBox над ListView с элементами Checkbox. Поэтому, когда я проверяю флажок, я применяю notifyDataSetChanged() чтобы проверить все проверки всех элементов списка. Поэтому в то время я получаю журналы для метода getView два раза, это означает, что getView получает вызов дважды, когда я notifyDataSetChanged() только один раз. Итак, может ли кто-нибудь сказать мне, почему я получаю журналы дважды? Также почему getView () вызывается дважды?

Основной класс –

 checkAll = (CheckBox) findViewById(R.id.my_check_box); checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton checkbox, boolean arg1) { adapter.notifyDataSetChanged(); } }); 

Код для адаптера –

  public class myAdapter extends ArrayAdapter<Model> { private final List<Model> list; private final Activity context; private CheckBox checkAll; public myAdapter(Activity context, List<Model> list, CheckBox checkAll) { super(context, R.layout.row, list); this.context = context; this.list = list; this.checkAll = checkAll; } static class ViewHolder { protected TextView text; protected CheckBox checkbox; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View view = null; if (convertView == null) { LayoutInflater inflator = context.getLayoutInflater(); view = inflator.inflate(R.layout.row, null); final ViewHolder viewHolder = new ViewHolder(); viewHolder.text = (TextView) view.findViewById(R.id.label); viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check); viewHolder.checkbox .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Model element = (Model) viewHolder.checkbox.getTag(); element.setSelected(buttonView.isChecked()); } }); view.setTag(viewHolder); viewHolder.checkbox.setTag(list.get(position)); } else { view = convertView; ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); } ViewHolder holder = (ViewHolder) view.getTag(); holder.text.setText(list.get(position).getName()); if(checkAll.isChecked() == true){ System.out.println(position+" checked th position"); } else if(checkAll.isChecked() == false){ System.out.println(position+" not checked th position"); } holder.checkbox.setChecked(list.get(position).isSelected()); return view; } } 

Выход LogCat Когда я могу adapter.notifyDataSetChanged(); На флажках CheckAll Проверьте регистратор изменений.

 11-30 20:31:33.751: INFO/System.out(1300): 0 checked th position 11-30 20:31:33.761: INFO/System.out(1300): 1 checked th position 11-30 20:31:33.770: INFO/System.out(1300): 2 checked th position 11-30 20:31:33.780: INFO/System.out(1300): 3 checked th position 11-30 20:31:33.810: INFO/System.out(1300): 4 checked th position 11-30 20:31:33.810: INFO/System.out(1300): 0 checked th position 11-30 20:31:33.831: INFO/System.out(1300): 1 checked th position 11-30 20:31:33.831: INFO/System.out(1300): 2 checked th position 11-30 20:31:33.851: INFO/System.out(1300): 3 checked th position 11-30 20:31:33.860: INFO/System.out(1300): 4 checked th position 

Вы можете видеть, что я вывод Logcat получаю один и тот же вывод два раза. Так может кто-нибудь сказать, почему это происходит?

Solutions Collecting From Web of "Странное поведение ListView с CheckBox"

Попробуйте сделать ListView height fill_parent .

Lisiview пытается самому настроить немного в соответствии с предоставленным пространством, это то, что я узнал, и похоже, что это причина.

Смотрите, помогает ли это.

На самом деле это не ответ на ваш вопрос – это просто, что у меня немного болит глаза, когда я вижу это:

 if(checkAll.isChecked() == true){ System.out.println(position+" checked th position"); } else if(checkAll.isChecked() == false){ System.out.println(position+" not checked th position"); } 

Оператор if-statement требует boolean выражение, и поскольку метод isChecked() возвращает boolean не нужно сопоставлять его с true/false . Кроме того, поскольку boolean может быть true или false , нет необходимости проверять их. Короче говоря, вы можете закипеть выше:

 if( checkAll.isChecked() ) System.out.println(position+" checked th position"); else System.out.println(position+" not checked th position"); 

Который намного более симпатичный 🙂

Не рассматривайте это как критику своих навыков программирования – просто рассматривайте это как возможность обучения.

Это bacause viewHolder внутри checkchangelistener будет меняться вместе со списком прокрутки. Поэтому никакое сопоставление между этим флажком и viewHolder не может использоваться таким образом.

Создайте класс sepatera checkchangelistener, реализующий checnChecnglistener. Передать checkchangelistener через конструктор.

НАПРИМЕР. Вне getView

 class MyCheckChangeLsitenet implements CompoundButton.OnCheckedChangeListener ViewHolder viewHolder MyCheckChangeLsitenet(ViewHolder viewHolder) { this.viewHolder = viewHolder ; } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Model element = (Model) viewHolder.checkbox.getTag(); element.setSelected(buttonView.isChecked()); } }); 

В GetView

ViewHolder.checkbox .setOnCheckedChangeListener (новый MycheckChangeListenet (viewHolder))