我有自定义simpleCursorAdapter
绑定的列表中的复选框列表。
在我的自定义simpleCursorAdapter
中,我已根据我的修改覆盖了newView
和bindView
。
我已经设法以某种方式做多重选择。
奇怪的是,在我从列表中删除任何项目后,突然检查第一项的复选框。这是怎么发生的?我该如何解决?
我的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);
}
}
};
答案 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。