带复选框的自定义 ListView
我知道有很多与带有复选框的自定义 ListView 相关的问题,但我在检索所有选中的项目时仍然遇到一些问题。
我正在做的是:
从数据库显示自定义ListView(所有已发送短信的列表)。
允许用户检查各种列表项。
当用户按下删除按钮时,我想删除所有选中的项目(从数据库以及视图部分)
问题: 当我第一次进入我的活动并检查一些项目并将其删除时,它工作正常。
但是,当我在按下删除按钮后再次检查某些项目时,有些项目被选中,有些项目未被选中,并且其他一些项目再次被删除。
我认为我无法完美绑定 id 和列表项目。
编码完成到目前为止:
row.xml 包含
ImageView
TextView
TextView
TextView
CheckBox
在我的 Activity 类中:
Uri uriSms = Uri.parse("content://sms/sent");
Cursor cursor = context.getContentResolver().query(uriSms, null,null,null,null);
String[] from={"address","body"};
int[] to={R.id.contactName,R.id.msgLine};
ssa=new SentSmsAdapter(context,R.layout.inbox_list_item,cursor,from,to,2);
smsList.setAdapter(ssa);
deleteSms.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ArrayList<Boolean> list=SentSmsAdapter.itemChecked;
Uri path=Uri.parse("content://sms/");
for(int i=0;i<list.size();i++)
{
if(list.get(i))
getContentResolver().delete(path,"_id="+ssa.getItemId(i),null);
}
ssa.notifyDataSetChanged();
}
我有自定义的 SimpleCursorAdapter。
public class SentSmsAdapter extends SimpleCursorAdapter{
Cursor dataCursor;
LayoutInflater mInflater;
Context context;
int layoutType;
ArrayList<String> arrayList;
public static HashMap<String,Long> myList=new HashMap<String,Long>();
public static ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
public static ArrayList<Long> itemIds=new ArrayList<Long>();
public SentSmsAdapter(Context context, int layout, Cursor dataCursor, String[] from,
int[] to,int type) {
super(context, layout, dataCursor, from, to);
layoutType=type;
this.context=context;
this.dataCursor = dataCursor;
mInflater = LayoutInflater.from(context);
arrayList=new ArrayList<String>();
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.inbox_list_item, null);
holder = new ViewHolder();
holder.checkBox=(CheckBox) convertView.findViewById(R.id.checkMsg);
holder.checkBox.setTag(position);
holder.cName=(TextView)convertView.findViewById(R.id.contactName);
holder.icon=(ImageView)convertView.findViewById(R.id.msgImage);
holder.msg=(TextView)convertView.findViewById(R.id.msgLine);
holder.time=(TextView)convertView.findViewById(R.id.msgTime);
convertView.setTag(holder);
holder.checkBox.setTag(itemChecked.get(position));
}
else
{
holder=(ViewHolder)convertView.getTag();
}
holder.checkBox.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) view.findViewById(R.id.checkMsg);
int pos=Integer.parseInt(holder.checkBox.getTag());
itemChecked.set(position, cb.isChecked());
/*if (cb.isChecked()) {
itemChecked.set(position, true);
Log.i("WhenChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
else if (!cb.isChecked()) {
itemChecked.set(position, false);
Log.i("WhenNotChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
*/
}
});
dataCursor.moveToPosition(position);
String id=Integer.toString(dataCursor.getInt(dataCursor.getColumnIndexOrThrow("_id")));
itemIds.add(Long.parseLong(id));
String msgText=dataCursor.getString(dataCursor.getColumnIndexOrThrow("body"));
holder.msg.setText(msgText);
Long time=dataCursor.getLong(dataCursor.getColumnIndexOrThrow("date"));
holder.time.setText(Long.toString(time));
String address=dataCursor.getString(dataCursor.getColumnIndexOrThrow("address"));
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
Cursor cs= context.getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},null,null,null);
if(cs.getCount()>0)
address=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME));
cs.close();
holder.cName.setText(address);
if(layoutType==1)holder.checkBox.setVisibility(View.GONE);
else
{
holder.checkBox.setVisibility(View.VISIBLE);
}
arrayList.add(id+","+address+","+msgText+","+Long.toString(time));
return convertView;
}
static class ViewHolder
{
ImageView icon;
CheckBox checkBox;
TextView cName;
TextView msg;
TextView time;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return arrayList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return itemIds.get(position);
}
}
I know there are lots of questions related to Custom ListView with CheckBox but still i am getting some problem in retrieving all checked items.
What i am doing is :
Displaying Custom ListView from Database (List of All Sent SMSs).
Allow user to check various list items.
When user presses the Delete Button i want to delete all the checked items (From the database as well as the view portion)
Problem :
When i go to my Activity for the first time and check some items, and delete it, it works fine.
But when i again check some items just after pressing delete button, some items gets checked and some gets unchecked and again some other items are deleted..
I think i am not able to bind id and list item perfectly..
Coding done so far:
row.xml contains
ImageView
TextView
TextView
TextView
CheckBox
In my Activity Class :
Uri uriSms = Uri.parse("content://sms/sent");
Cursor cursor = context.getContentResolver().query(uriSms, null,null,null,null);
String[] from={"address","body"};
int[] to={R.id.contactName,R.id.msgLine};
ssa=new SentSmsAdapter(context,R.layout.inbox_list_item,cursor,from,to,2);
smsList.setAdapter(ssa);
deleteSms.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
ArrayList<Boolean> list=SentSmsAdapter.itemChecked;
Uri path=Uri.parse("content://sms/");
for(int i=0;i<list.size();i++)
{
if(list.get(i))
getContentResolver().delete(path,"_id="+ssa.getItemId(i),null);
}
ssa.notifyDataSetChanged();
}
I have custom SimpleCursorAdapter.
public class SentSmsAdapter extends SimpleCursorAdapter{
Cursor dataCursor;
LayoutInflater mInflater;
Context context;
int layoutType;
ArrayList<String> arrayList;
public static HashMap<String,Long> myList=new HashMap<String,Long>();
public static ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
public static ArrayList<Long> itemIds=new ArrayList<Long>();
public SentSmsAdapter(Context context, int layout, Cursor dataCursor, String[] from,
int[] to,int type) {
super(context, layout, dataCursor, from, to);
layoutType=type;
this.context=context;
this.dataCursor = dataCursor;
mInflater = LayoutInflater.from(context);
arrayList=new ArrayList<String>();
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.inbox_list_item, null);
holder = new ViewHolder();
holder.checkBox=(CheckBox) convertView.findViewById(R.id.checkMsg);
holder.checkBox.setTag(position);
holder.cName=(TextView)convertView.findViewById(R.id.contactName);
holder.icon=(ImageView)convertView.findViewById(R.id.msgImage);
holder.msg=(TextView)convertView.findViewById(R.id.msgLine);
holder.time=(TextView)convertView.findViewById(R.id.msgTime);
convertView.setTag(holder);
holder.checkBox.setTag(itemChecked.get(position));
}
else
{
holder=(ViewHolder)convertView.getTag();
}
holder.checkBox.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) view.findViewById(R.id.checkMsg);
int pos=Integer.parseInt(holder.checkBox.getTag());
itemChecked.set(position, cb.isChecked());
/*if (cb.isChecked()) {
itemChecked.set(position, true);
Log.i("WhenChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
else if (!cb.isChecked()) {
itemChecked.set(position, false);
Log.i("WhenNotChecked",Boolean.toString(itemChecked.get(position)));
// do some operations here
}
*/
}
});
dataCursor.moveToPosition(position);
String id=Integer.toString(dataCursor.getInt(dataCursor.getColumnIndexOrThrow("_id")));
itemIds.add(Long.parseLong(id));
String msgText=dataCursor.getString(dataCursor.getColumnIndexOrThrow("body"));
holder.msg.setText(msgText);
Long time=dataCursor.getLong(dataCursor.getColumnIndexOrThrow("date"));
holder.time.setText(Long.toString(time));
String address=dataCursor.getString(dataCursor.getColumnIndexOrThrow("address"));
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
Cursor cs= context.getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},null,null,null);
if(cs.getCount()>0)
address=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME));
cs.close();
holder.cName.setText(address);
if(layoutType==1)holder.checkBox.setVisibility(View.GONE);
else
{
holder.checkBox.setVisibility(View.VISIBLE);
}
arrayList.add(id+","+address+","+msgText+","+Long.toString(time));
return convertView;
}
static class ViewHolder
{
ImageView icon;
CheckBox checkBox;
TextView cName;
TextView msg;
TextView time;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return arrayList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return itemIds.get(position);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试这样的事情。
在 getView() 中添加此代码,
在 getView() 之外实现此代码。
删除时,删除列表中索引在 itemChecked 中可用的所有元素。
Try something like this.
add this code in getView()
implement this outside getView().
When deleting delete all the elements from the list whose index is available in itemChecked.
如果您在检查、取消检查和删除项目时使用线程,它们将正常工作。
If you use threads when checking, uncheking and deleting your items, they will work properly.