【问题标题】:Custom ListView with CheckBox带有复选框的自定义 ListView
【发布时间】:2011-07-14 13:54:21
【问题描述】:

我知道有很多与使用 CheckBox 的自定义 ListView 相关的问题,但在检索所有选中的项目时我仍然遇到一些问题。

我正在做的是:

显示来自数据库的自定义 ListView(所有已发送 SMS 的列表)。

允许用户检查各种列表项。

当用户按下删除按钮时,我想删除所有选中的项目(从数据库以及视图部分)

问题: 当我第一次去我的活动并检查一些项目并将其删除时,它工作正常。

但是当我在按下删除按钮后再次检查一些项目时,一些项目被选中,一些被取消选中,并且再次删除了一些其他项目..

我认为我无法完美地绑定 id 和 list item..

目前已完成编码

row.xml 包含

ImageView
TextView
TextView
TextView
CheckBox 

在我的活动课中:

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);
    }

}

【问题讨论】:

    标签: android android-listview android-custom-view android-cursor


    【解决方案1】:

    试试这样的。

    在getView()中添加这段代码

    holder.checkBox.seTag(position);
    holder.checkBox.setOnCheckedChangedListener(this);
    

    在 getView() 外部实现。

    public void onCheckedChanged(CompoundButton view,boolean isChecked) {
    
      if(isChecked)
        {
          itemChecked.add(view.getTag());                          
        }
        else
        {
            if(itemChecked.cantains(view.getTag()))
              //remove from itemChecked.
        }
    }
    

    删除时从列表中删除其索引在 itemChecked 中可用的所有元素。

    谢谢,N-JOY。

    【讨论】:

    • 我有一个类似于 Kartik 的类,但我使用的是 ArrayAdapter。单击其中一个复选框时,会为所有这些复选框调用 onCheckChanged 事件。我使用 ArrayAdapter 的事实不应该改变这一点吗?
    • 我使用了 onClick 而不是 onCheckedChanged 就像我在这里读到的 (stackoverflow.com/questions/5438375/…) 并且我得到了它的工作。
    【解决方案2】:

    如果您在检查、取消检查和删除项目时使用线程,它们将正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 2014-05-03
      • 2012-08-13
      相关资源
      最近更新 更多