ListView中的CheckBox在离开屏幕时被重置

时间:2014-09-19 12:35:31

标签: android android-listview android-arrayadapter android-checkbox

我已按照教程here创建了一个自定义ListView,其中显示了带有类别标题的项目。我修改了list_item_entry.xml以在项目中添加CheckBox

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize" >

    <CheckBox
        android:id="@+id/option_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="6dp"
        android:focusable="false"
        android:clickable="false" />

    <TextView
        android:id="@+id/list_item_entry_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:gravity="center_vertical"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"
        android:ellipsize="marquee"
        android:fadingEdge="horizontal" />

</LinearLayout>

我的问题是,如果我检查一些CheckBoxes然后将它们从屏幕滚动,当它们返回时它们是未经检查的。但是,listView.getCheckedItemPositions()仍然显示该项目为checked

我很确定我的问题在于我的自定义getView()中的ArrayAdapter方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Item i = items.get(position);
    if (i != null) {
        if(i.isSection()){
            SectionItem si = (SectionItem)i;
            convertView = vi.inflate(R.layout.list_item_section, parent, false);

            convertView.setOnClickListener(null);
            convertView.setOnLongClickListener(null);
            convertView.setLongClickable(false);

            final TextView sectionView =
                     (TextView) convertView.findViewById(R.id.list_item_section_text);
            sectionView.setText(si.getTitle());
        }else{
            EntryItem ei = (EntryItem)i;
            convertView = vi.inflate(R.layout. list_item_entry, parent, false);
            final TextView title =
                     (TextView) convertView.findViewById(R.id.list_item_entry_title);
            if (title != null) 
                title.setText(ei.getTitle());
        }
    }
    return convertView;
 }

我认为我在这里有两个问题,但我不知道如何解决:

  1. 每次使用vi.inflate会导致android不断创建不好的视图(不确定)。我试图仅在convertView == null时对其进行充气,但有时convertView的格式错误,即。 List_item_section时应为List_item_entry。每次充气都可以吗?

  2. 我认为每次增加视图会导致CheckBoxes被重置,虽然我可能错了。

  3. 那么如何制作它以便CheckBoxes在离开并返回屏幕时保持检查状态?如果列表足够长,这个方法是否会使用Views填充Android的内存?

    更新: 我喜欢@ user3815165的答案,因为我不需要为没有复选框的checked存储sectionItem值。但正如我在评论中提到的,由于items列表不在Activity的上下文中,因此在视图被销毁并创建错误时,是否检查每个EntryItem的值是否仍然存在。< / p>

    所以我决定使用@ Palash的答案,即使它不需要存储数据(列表中每个boolean只有一个SectionItem值)。它运作得很好。

2 个答案:

答案 0 :(得分:0)

您需要在活动中维护boolean类型的状态数组,将该数组传递到列表适配器中,同时设置该位置的复选框检查状态,同样需要在复选框的click事件上更新该状态数组。 试试这个你会得到所需的输出。

//While Setting the checkbox in adapter

     if(bStatus[position]==false)
        {
             itemSet.chSelectItem.setChecked(false);
        }else if(bStatus[position]==true)
            {
              itemSet.chSelectItem.setChecked(true);
            }   

在您的主要活动

      //initilize Arraylist in main Activity
        boolean[] bStatus;
        bStatus = new boolean[BeanArray.size()];
        Arrays.fill(bStatus, false);
    MyAdapter adapter = new MyAdapter(this, BeanArray, bStatus);
listView.setAdapter(adapter);

答案 1 :(得分:0)

class Item{
 boolean isSection;
 String title;
 boolean isOptionChecbox;

 //your getter/setter

    @Override
    public String toString() {
        return title;
    }
}

you Adapter:
public class listAdapter extends ArrayAdapter<Item> {

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final Item i = items.get(position);
    if(i.isSection()){
              convertView = vi.inflate(R.layout.list_item_section, parent, false);
              convertView.setOnClickListener(null);
              convertView.setOnLongClickListener(null);
              convertView.setLongClickable(false);
              final TextView sectionView = (TextView) convertView.findViewById(R.id.list_item_section_text);
              sectionView.setText(si.getTitle());
       } else{
              convertView = vi.inflate(R.layout. list_item_entry, parent, false);
              final TextView title = (TextView) convertView.findViewById(R.id.list_item_entry_title);
              if (title != null) title.setText(ei.getTitle());

              CheckBox optionCheckbox = (CheckBox) convertView.findViewById(R.id.option_checkbox);
              optionCheckbox.setChecked(ei.isOptionCheckbox());
              optionCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                  @Override
                  public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                      item.setOptionCheckbox(b);
                  }
            });
       }      
    return convertView;
 }

}