列表中的复选框被意外检查

时间:2010-02-16 00:31:47

标签: android android-contentprovider simplecursoradapter

我有自定义simpleCursorAdapter绑定的列表中的复选框列表。 在我的自定义simpleCursorAdapter中,我已根据我的修改覆盖了newViewbindView。 我已经设法以某种方式做多重选择。 奇怪的是,在我从列表中删除任何项目后,突然检查第一项的复选框。这是怎么发生的?我该如何解决?

我的SimpleCursorAdapter课程:

public class MyListCursorAdapter extends SimpleCursorAdapter
{
    private Context context;
    private int layout;

    public MyCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to)
    {
        super(context, layout, c, from, to);
        this.context = context;
        this.layout = layout;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent)
    {
        Cursor c = getCursor();
        final LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(layout, parent, false);
        CheckBox chkBoxBtn = (CheckBox) v.findViewById (R.id.deleteTwittChkBox);
        if (chkBoxBtn != null)
        {
            chkBoxBtn.setChecked(false);
        }
        return v;
    }

    @Override
    public void bindView(View v, Context context, Cursor c)
    {
        --binding view to my textsview in my items
        //now it's the importat part:
            CheckBox chkBoxBtn = (CheckBox) v.findViewById(R.id.deleteTwittChkBox);
    if (chkBoxBtn != null)
    {
        chkBoxBtn.setId(Integer.valueOf(c.getString(c
                .getColumnIndex(MyUsers.User._ID))));
        chkBoxBtn.setOnClickListener(new OnItemClickListener(chkBoxBtn, v));
        chkBoxBtn.setChecked(false);
    }
    }

    //i couldnt find another way of doing this, but this is how i set listeners to my checkboxses
    static ArrayList<String> checkedItemsList = new ArrayList<String>();

    private class OnItemClickListener implements OnClickListener
    {
        private int mPosition;
        private CheckBox chkBox;
        OnItemClickListener(CheckBox mChkBox, View v)
        {
            chkBox = mChkBox;
            chkBox.setChecked(false);
        }

        @Override
        public void onClick(View v)
        {
            if (chkBox.isChecked())
            {
                checkedItemsList.add(String.valueOf(chkBox.getId()));
            }
            else
            {
                checkedItemsList.remove(String.valueOf(chkBox.getId()));
            }
        }
    }
}

以下是ListActivity类的代码部分,它描述了删除已选中复选框项的按钮:

OnClickListener btListener = new OnClickListener()
{
    public void onClick(View view)
    {
        // long[] items = listView.getCheckItemIds();
        int x = 0;
        Uri myUri = Uri
        .parse("content://com.idan.datastorageprovider/users");
        String where = "_id" + "=?";
        //here i am tatking all checkboxes which ive added from the  adapter class
        ArrayList<String> checkedItemsList =   MySimpleCursorAdapter.checkedItemsList;
        for (String itemID : checkedItemsList)
        {
            getContentResolver()
            .delete(myUri, where, new String[] { itemID});
            checkedItemsList.remove(itemID);
        }
    }
};

3 个答案:

答案 0 :(得分:2)

我怀疑SimpleCursorAdapter是在这里扩展的合适类。

“已检查”状态是否以任何方式连接到数据XML?没有?所以你需要自己的定制适配器!

基本上所有适配器都必须实现一种从给定元素生成视图的方法(更确切地说是元素位置!)。这将在列表要显示元素的任何时候调用。现在,它使用的技巧是重新使用以前创建的列表视图元素,这些元素在屏幕上再也看不到了!因此:当你向下滚动列表并且元素在顶部消失时,这个视图对象将被重新用于下一个出现的项目。

因此,当使用应该重用的给定“旧”视图调用此方法时,必须根据元素数据设置所有包含的元素。如果复选框是此游戏的一部分,则必须为已检查状态设置存储空间!仅有一个复选框是不够的,因为列表元素会有更少的复选框对象!

SimpleCursorAdapters是 - 是的 - 代表简单的东西。描述数据的XML(图像和文本,如文档所述)。由于这种简单性,您在此处所要做的就是提供一种创建NEW元素视图对象的方法 - 您不会在任何时候拦截重用过程!它基本上只知道如何将数据放入现有的视图对象 - 但它缺乏如何处理已检查/未检查的框的知识!

您的解决方案:编写您自己的BaseAdapter扩展并执行必须执行的操作:实现“getView”(以及其他一些方法,如getItem,getItemId和getCount)。这一点都不难! 此API Demo使用BaseAdapter,此处mExpanded状态与您的复选框状态基本相同!

祝你好运!

答案 1 :(得分:0)

修改数据时可能需要调用notifyDataSetChanged

答案 2 :(得分:0)

问题可能是你在onItemClickListener中调用setChecked。一个hacky方法是在你的监听器中调用setChecked之前和之后执行以下操作:

chkBox.setClickable(false);
chkBox.setChecked(false);
checkBox.setClickable(true);

这将阻止在手动调用setChecked时调用onItemClickListener。