项目视图已删除,但仍在ListView中使用CustomAdapter检查复选框

时间:2017-12-13 20:44:55

标签: android listview checkbox

我在片段中有ListView控件(CoordinatorLayout)。 ListView的每一行都是TableLayout,其中包含CheckBox控件。

如果我检查第一行,则调用片段中的DeleteSelection方法,然后删除第一行视图。但是新的第一行还有一个复选框仍然被检查!!

我查了十几篇关于ListView的帖子并删除了一些项目,但我仍然无法理解......我变得疯狂了......请帮助。

row.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TableRow>

        <TextView
            android:id="@+id/txtCourt"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:paddingLeft="5dp"
            android:paddingRight="5dp" />

        <CheckBox
            android:id="@+id/chkSelect"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"/>
</TableRow>
</TableLayout>

MyFragment.java

public class MyFragment extends Fragment {
    private Context mContext;
    private ListView listView1;
    private List<MyObject> mylist = new ArrayList<>();

在覆盖onViewCreated方法中,我初始化listview和适配器:

    for(int i=1; i<5; i++) {
        MyObject res = new MyObject();
        res.mytextBla = "bla" + i;
        this.mylist.add(res);
    }

    this.mAdapter = new CustomAdapter(this.mylist, getActivity().getApplicationContext());
    this.listview1.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    this.listview1.setAdapter(mAdapter);

再远一点:

public void DeleteSelection() {

    SparseBooleanArray arr = mAdapter.getSelectedIds();
    for(int i = (arr .size()-1); i >=0; i--) {
        if (arr.valueAt(i)) {
            MyObject res = mAdapter.getItem(arr.keyAt(i));
            this.mylist.remove(res);
        }
    }
    mAdapter.removeSelection();

}

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<MyObject> {
    private SparseBooleanArray mSelectedItemsIds;
    private List<MyObject> mylist;

    private Context mContext;

    public mylistAdapter(List<MyObject> mylist, Context context) {
        super(context, R.layout.row, mylist);
        this.mylist = mylist;
        this.mContext=context;
        mSelectedItemsIds = new SparseBooleanArray();
    }

    public void toggleSelection(int position) {
        selectView(position, !mSelectedItemsIds.get(position));
    }

    @Override
    public void remove(MyObject object) {
        this.mylist.remove(object);
        notifyDataSetChanged();
    }

    public void removeSelection() {
        mSelectedItemsIds.clear(); // = new SparseBooleanArray();
        notifyDataSetChanged();
    }

    public void selectView(int position, boolean value) {
        if (value)
            mSelectedItemsIds.put(position, value);
        else
            mSelectedItemsIds.delete(position);
        notifyDataSetChanged();
    }

    public SparseBooleanArray getSelectedIds() {
        return mSelectedItemsIds;
    }

    public void refresh(ArrayList<MyObject> mylist) {
        this.mylist = mylist;
        this.clear();
        this.addAll(mylist);
        this.notifyDataSetChanged();

    }

    // View lookup cache
    private static class ViewHolder {
        CheckBox chkSelect;
        TextView txtBla;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // Get the data item for this position
        MyObject dataModel = getItem(position);
        ViewHolder viewHolder; // view lookup cache stored in tag

        final View result;

        if (convertView == null) {

            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.row, null); //parent, false);
            viewHolder.txtBla = convertView.findViewById(R.id.txtBla);
            viewHolder.chkSelect = convertView.findViewById(R.id.chkSelect);
            viewHolder.chkSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    toggleSelection(position);
                }
            });
            result = convertView;
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
            result=convertView;
        }

        viewHolder.txtBla.setText(dataModel.mytextBla);

        // Return the completed view to render on screen
        return convertView;
    }
}

谢谢!

1 个答案:

答案 0 :(得分:0)

您的适配器中的getView()方法实际上并未设置复选框的选中状态。每次重新使用视图时,都应确保正确设置检查状态。像

这样的东西
viewHolder.ckhSelect.setChecked(mSelectedItemIds.get(position));

请注意,这会触发您的OnCheckedChangeListener()。一个简单的解决方法是将侦听器设置为null,然后在修改复选框的选中状态后将其重新设置为实际值,但也有其他(更复杂的)方法。