0

我一直在使用 a中定义的ListView每个项目 aCheckableLinearLayout

CheckableLinearLayout

我无法检查 中的任何行ListView,它甚至没有在 UI 中注册检查。我不相信有一个android:checkMarkfor CheckableLinearLayoutCheckedTextView嵌套在 my 内部是否正确,CheckableLinearLayout如果我使用 aCheckBox代替会更好。另外,如何在ArrayList检查它们后立即将它们放入其中,而不是以这种方式迭代它们。

这是我的布局:

   <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>

我已经实现了 listActivity 如下:

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

    });

}   

 }

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

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

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

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

现在,当我尝试访问正在使用的 ArrayList 时,它会引发 ArrayOutOfBoundsException:

    btn_del.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
            new Thread()
            {
                public void run()
                {
                    int count=lv.getCount();
                    for(int i=0;i<count;i++)
                    {
                        if(adapter.hitList.get(i))
                        {
                            db.delete(c.getInt(c.getColumnIndex(TumblrDB._ID)));
                        }
                    }
                }
            }.start();
            adapter.notifyDataSetChanged();
        }
    });
4

1 回答 1

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 方法保存并在侦听器中检索以确定位置已选中的复选框。

   @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");
            //}

        }});

曾经,您已经从行中删除了数据,在您调用游标上的 requery(已弃用...需要找到更好的替代方法)之前,必须重置 ArrayList 中的值。

于 2013-10-08T11:27:04.077 回答