从ArrayList中的列表视图中保存复选框状态

时间:2013-10-07 07:45:15

标签: java android listview checkedtextview

我一直在使用ListView,每个项目都是{/ 1}},如

中所定义

CheckableLinearLayout

我无法检查CheckableLinearLayout中的任何行,它甚至没有在UI中注册检查。我认为ListView不存在android:checkMark。将CheckableLinearLayout嵌套到我的CheckedTextView中是否正确,如果我使用CheckableLinearLayout代替它会更好。另外,如何在检查后将它们放在CheckBox中,而不是以这种方式迭代它们。

这是我的布局:

ArrayList

我已经实现了listActivity,如下所示:

   <com.example.deltest.CheckableLinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 >
<CheckedTextView 
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
 />
<TextView android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/txt_a"
          />
<TextView android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/txt_b"
    />

   </com.example.deltest.CheckableLinearLayout>

编辑尝试通过扩展SimpleCursorAdapter解决问题的不同方法:

    public class DeleteList extends ListActivity 
    {
    ArrayList<Integer> idList=new ArrayList<Integer>();
    Cursor  c;
    Handler handler;
    static final int WHAT=0;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    final TumblrDB db=new TumblrDB(this);
    c=db.query();
    startManagingCursor(c);
    handler=new Handler();
    View v=getLayoutInflater().inflate(R.layout.layout_header, null,false);
    getListView().addHeaderView(v);
    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.layout_del,c,new String[] {TumblrDB.DATE,TumblrDB.DESC},new int[]{R.id.txt_a,R.id.txt_b});
    getListView().setAdapter(adapter);
    if(handler.hasMessages(WHAT))
    {
        c=db.query();
        ((SimpleCursorAdapter)getListView().getAdapter()).swapCursor(c);
    }

    Button btn_del=(Button)v.findViewById(R.id.btn_del);
    btn_del.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
            int count=getListView().getCount();
            SparseBooleanArray sparseBooleanArray=getListView().getCheckedItemPositions();
            for(int i=0;i<count;i++)
            {
                if(sparseBooleanArray.get(i))
                {
                    c.moveToPosition(i);
                    int _id=c.getInt(c.getColumnIndex(TumblrDB._ID));
                    Log.d("DeleteList", "The id has been added "+_id);
                    idList.add(_id);
                    new Thread()
                    {
                        public void run()
                        {
                            for(int i:idList)
                            {
                                db.delete(i);
                                Log.d("DeleteList", "The id has been deleted "+i);
                                handler.sendEmptyMessage(WHAT);
                            }
                        }
                    }.start();
                }
            }
        }

    });

}   

 }

然后我为CheckBox实现了一个OnClickListener:

    if(row==null)
    {
        row=inflater.inflate(layout, null, false);
        holder=new ViewHolder(row,position);
        row.setTag(holder);
        holder.check_del.setTag(position);
    }
    else
    {
        holder=(ViewHolder)row.getTag();
        holder.check_del.setOnClickListener(null);
        holder.check_del.setTag(position);
        if(hitList.get(position))
            holder.check_del.setChecked(true);
        else
            holder.check_del.setChecked(false);
    }

现在,当我尝试访问我正在使用的ArrayList时,它会抛出一个ArrayOutOfBoundsException:

      OnClickListener cbl=new OnClickListener(){

        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
            int position=(Integer)view.getTag();
            Log.d("CustomCursorAdapter", "The checkbox at postion "+position+" has been clicked");
            if(((CheckBox)view).isChecked())
            {
                hitList.set(position, true);
            }
            else 
            {
                hitList.set(position, false);
            }
        }
    };  

1 个答案:

答案 0 :(得分:1)

使用ArrayList存储列表中所有复选框的状态。

   public static ArrayList<Boolean> hitList;

我已初始化并将所有值设置为false:

    hitList=new ArrayList<Boolean>();
    for(int i=0;i<this.getCount();i++)
    {
        hitList.add(i, false);
    } 

当初始化View的复选框时,它按位置查找数组并仅在ArrayList中的值为true时检查它。位置由CheckBox使用它的setTag方法保存并在Listener中检索以确定已选中的复选框的位置。

   @Override
public View getView(int position,View convertView,ViewGroup parent)
{
    View row=convertView;
    ViewHolder holder;

    if(row==null)
    {
        row=inflater.inflate(layout, null, false);
        holder=new ViewHolder(row);
        row.setTag(holder);
        holder.check_del.setTag(position);
    }
    else
    {
        holder=(ViewHolder)row.getTag();
        holder.check_del.setOnClickListener(null);
        holder.check_del.setTag(position);
        if(hitList.get(position))
            holder.check_del.setChecked(true);
        else
            holder.check_del.setChecked(false);
    }
    c.moveToPosition(position);
    holder.txt_a.setText(c.getString(c.getColumnIndex(ItemDB.TITLE)));
    holder.txt_b.setText(c.getString(c.getColumnIndex(ItemDB.DESCRIPTION)));

    OnClickListener cbl=new OnClickListener(){

        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
            int position=(Integer)view.getTag();
            Log.d("CustomCursorAdapter", "The checkbox at postion "+position+" has been clicked");
            if(((CheckBox)view).isChecked())
            {
                hitList.set(position, true);
            }
            else 
            {
                hitList.set(position, false);
            }
        }
    };  

    holder.check_del.setOnClickListener(cbl);
    return row;
}

static class ViewHolder
{
    TextView txt_a;
    TextView txt_b;
    CheckBox check_del;
    ViewHolder(View row)
    {
        txt_a=(TextView)row.findViewById(R.id.txt_a);
        txt_b=(TextView)row.findViewById(R.id.txt_b);
        check_del=(CheckBox)row.findViewById(R.id.check_del);
    }
}

目前,我在ListView中有一个标题,其中包含以下onClickListener:

    @SuppressWarnings("deprecation")
        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
            ArrayList<Boolean> killList=CustomCursorAdapter.hitList;
            int totalDeleted=0;
            for(int i=0;i<killList.size();i++)
            {
                //Log.d(TAG,i+":"+killList.get(i));
                c.moveToPosition(i);
                String title=c.getString(c.getColumnIndex(ItemDB.TITLE));
                int _id=c.getInt(c.getColumnIndex(ItemDB._ID));
                //Log.d(TAG, "Item has title "+title+" and id "+_id );
                int rowsAffected=0;
                if(killList.get(i))
                {
                    rowsAffected=db.delete(_id);
                    //Log.d(TAG, "Deleted row with id "+_id);
                    killList.set(i, false);

                }
                totalDeleted+=rowsAffected;

            }
            //Log.d(TAG, "The total number of rows deleted "+totalDeleted);
            //if(c.requery())
            //{
                //Log.d(TAG, "Requerying data,this calls notifyDataSetChanged");
            //}

        }});

一旦你在Cursor上调用requery之前已经从行中删除了数据(不推荐使用它...需要找到更好的选择),必须重置ArrayList中的值。