Android:CursorAdapter、ListView和CheckBox

Android:CursorAdapter、ListView和CheckBox,android,listview,checkbox,Android,Listview,Checkbox,我有自己的布局和CustomCursorAdapter的ListView。每行都有自己的复选框。所以很明显,在sroll过程中,复选框会失去其状态。我找到的唯一的东西是,但是没有答案。 还有一个问题。我的客户适应性也有同样的问题。我使用SparseBooleanArray来保存复选框状态,从而解决了这个问题。它工作正常,但每个滚动调用onCheckedChanged。这正常吗?deal is my list视图描述了报警元素和(onCheckedChanged的)启动/停止报警的定期调用。很多不

我有自己的布局和CustomCursorAdapter的ListView。每行都有自己的复选框。所以很明显,在sroll过程中,复选框会失去其状态。我找到的唯一的东西是,但是没有答案。
还有一个问题。我的客户适应性也有同样的问题。我使用SparseBooleanArray来保存复选框状态,从而解决了这个问题。它工作正常,但每个滚动调用onCheckedChanged。这正常吗?deal is my list视图描述了报警元素和(onCheckedChanged的)启动/停止报警的定期调用。很多不必要的操作。

我的
列表视图
复选框
有类似的问题,我做了什么来解决这个问题:

  • 创建布尔对象的ArrayList以存储每个复选框的状态
  • 将ArrayList项初始化为默认值
    false
    ,表示尚未选中任何复选框
  • 当你点击复选框时。针对选中/未选中状态设置检查,并将该值存储在ArrayList中
  • 现在使用setChecked()方法将该位置设置为CheckBox
请参阅以下代码片段:
公共类MyDataAdapter扩展了SimpleCursorAdapter{
专用游标c;
私人语境;
private ArrayList list=new ArrayList();
private ArrayList itemChecked=新建ArrayList();
//itemChecked将存储选中项目的位置。
公共MyDataAdapter(上下文上下文、int布局、光标c、字符串[]from、,
int[]至){
super(上下文、布局、c、from、to);
这个.c=c;
this.context=上下文;
for(int i=0;i
当ListView中有可检查项时,会有一些问题。我建议建立以下链接:


我想这很接近你想要的

我也面临着类似的问题,所以在大量阅读之后,我像这样解决了这个问题:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listview, null);
            holder = new ViewHolder();
            holder.nameView = (TextView)convertView.findViewById(R.id.textView1);
            holder.numberView = (TextView)convertView.findViewById(R.id.textView2);
            holder.cb = (CheckBox)convertView.findViewById(R.id.checkBox1);
            convertView.setTag(holder);                
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        holder.nameView.setText(mData.get(position).toString());
        holder.numberView.setText(mNumber.get(position).toString());
        holder.cb.setChecked(false);
        holder.cb.setTag(position);



        if(selected.indexOf(mNumber.get(position).toString()) >= 0)
        {

        holder.cb.setChecked(true);
        }

        return convertView;
    }

}

在这里,我在getView()上执行的操作是取消选中所有复选框,然后根据它对应的文本视图手动再次选中需要选中的复选框。因此,如果用户在选中第一个复选框后向下滚动,视图中的所有复选框都将被取消选中,如果他再次向上滚动,则所有复选框也将被取消选中,但他之前单击的复选框将再次被重新检查。

我决定尝试使用setViewBinder方法。СHECKBOX状态存储在SPARSEBOOLEAN数组中。 Сheckbox状态随着您单击复选框本身和整个单元格而改变

我的行:|文本视图|复选框|

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//        ..
    private SparseBooleanArray checkedItems = new SparseBooleanArray(); //for storing item state

    startManagingCursor(cursor);
    String[] from = new String[] { dbAdapter.COLUMN_NAME, dbAdapter.COLUMN_CHECK };
    int[] to = new int[] { R.id.item_name, R.id.item_check };
    recordsAdapter = new SimpleCursorAdapter(this, R.layout.items, cursor, from, to);

    recordsAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            if (columnIndex == 2) { //2 - R.id.item_check
                    final CheckBox cb = (CheckBox) view; 
                    final int rowID = cursor.getInt(0); //cursor.getInt(0) - _id from table

                    if (checkedItems.indexOfKey(rowID) >= 0) {  //checkedItems contains rowID?
                        cb.setChecked(checkedItems.get(rowID));
                    } else if (cursor.getInt(2) > 0) {          //cursor.getInt(2): 0 - false, 1 - true
                        checkedItems.append(rowID, true);
                        cb.setChecked(true);
                    } else {
                        cb.setChecked(false);
                    }

                    cb.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (checkedItems.indexOfKey(rowID) >= 0) {
                                checkedItems.put(rowID, !(checkedItems.get(rowID)));
                            } else {
                                checkedItems.append(rowID, true);
                            }
                            cb.setChecked(checkedItems.get(rowID));
                            dbAdapter.updateItem(rowID, checkedItems.get(rowID)?1:0);
                        }
                    });
                    return true;
            }
            return false;
        }
    });

    itemsList.setAdapter(recordsAdapter);
    itemsList.setOnItemClickListener(this);
//      ..
}

//if click on TextView of row - CheckBox of row is set/unset
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
    TextView tv = (TextView) view.findViewById(R.id.item_name);
    ViewGroup row = (ViewGroup) tv.getParent();
    CheckBox cb = (CheckBox) row.getChildAt(1);
    cb.performClick();
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//        ..
private SparseBooleanArray checkedItems=new SparseBooleanArray();//用于存储项状态
开始管理游标(游标);
String[]from=新字符串[]{dbAdapter.COLUMN_NAME,dbAdapter.COLUMN_CHECK};
int[]to=newint[]{R.id.item_name,R.id.item_check};
recordsAdapter=新的SimpleCorsorAdapter(this,R.layout.items,游标,from,to);
recordsAdapter.setViewBinder(新的SimpleCursorAdapter.ViewBinder(){
公共布尔setViewValue(视图、光标、int-columnIndex){
如果(columnIndex==2){//2-R.id.item\u检查
最终复选框cb=(复选框)视图;
final int rowID=cursor.getInt(0);//cursor.getInt(0)——\u表中的id
如果(checkedItems.indexOfKey(rowID)>=0){//checkedItems包含rowID?
cb.setChecked(checkedItems.get(rowID));
}else如果(cursor.getInt(2)>0){//cursor.getInt(2):0-false,1-true
append(rowID,true);
cb.setChecked(真);
}否则{
cb.setChecked(假);
}
cb.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
if(checkedItems.indexOfKey(rowID)>=0){
checkedItems.put(rowID,!(checkedItems.get(rowID));
}否则{
append(rowID,true);
}
cb.setChecked(checkedItems.get(rowID));
dbAdapter.updateItem(rowID,checkedItems.get(rowID)?1:0;
}
});
返回true;
}
返回false;
}
});
itemsList.setAdapter(recordsAdapter);
itemsList.setOnItemClickListener(此);
//      ..
}
//如果单击行的文本视图-设置/取消设置行的复选框
@O
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//        ..
    private SparseBooleanArray checkedItems = new SparseBooleanArray(); //for storing item state

    startManagingCursor(cursor);
    String[] from = new String[] { dbAdapter.COLUMN_NAME, dbAdapter.COLUMN_CHECK };
    int[] to = new int[] { R.id.item_name, R.id.item_check };
    recordsAdapter = new SimpleCursorAdapter(this, R.layout.items, cursor, from, to);

    recordsAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            if (columnIndex == 2) { //2 - R.id.item_check
                    final CheckBox cb = (CheckBox) view; 
                    final int rowID = cursor.getInt(0); //cursor.getInt(0) - _id from table

                    if (checkedItems.indexOfKey(rowID) >= 0) {  //checkedItems contains rowID?
                        cb.setChecked(checkedItems.get(rowID));
                    } else if (cursor.getInt(2) > 0) {          //cursor.getInt(2): 0 - false, 1 - true
                        checkedItems.append(rowID, true);
                        cb.setChecked(true);
                    } else {
                        cb.setChecked(false);
                    }

                    cb.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (checkedItems.indexOfKey(rowID) >= 0) {
                                checkedItems.put(rowID, !(checkedItems.get(rowID)));
                            } else {
                                checkedItems.append(rowID, true);
                            }
                            cb.setChecked(checkedItems.get(rowID));
                            dbAdapter.updateItem(rowID, checkedItems.get(rowID)?1:0);
                        }
                    });
                    return true;
            }
            return false;
        }
    });

    itemsList.setAdapter(recordsAdapter);
    itemsList.setOnItemClickListener(this);
//      ..
}

//if click on TextView of row - CheckBox of row is set/unset
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
    TextView tv = (TextView) view.findViewById(R.id.item_name);
    ViewGroup row = (ViewGroup) tv.getParent();
    CheckBox cb = (CheckBox) row.getChildAt(1);
    cb.performClick();
}
<CheckBox
    android:id="@+id/myCheckBox[]"
    android:focusable="false"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true" />
@Override
        public void bindView(View view, Context context, Cursor cursor) {

            final ViewHolder holder = (ViewHolder) view.getTag();
            final int position = cursor.getPosition();
            String name = (cursor.getString(cursor.getColumnIndexOrThrow("NotificationDateFor")));
            String image = cursor.getString(cursor.getColumnIndexOrThrow("imageUri"));

             System.out.println("cursor.getPosition(test): "+cursor.getPosition());

            holder.nametext.setText(name);
        //  setImage(image, holder.iv); 


            holder.chk.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v) {

                        if (holder.chk.isChecked()) {
                            itemChecked.set(position, true);
                           System.out.println("cursor.getPosition(true): "+position);
                        } else if (!holder.chk.isChecked()) {
                            itemChecked.set(position, false);
                            System.out.println("cursor.getPosition(false): "+position);
                            // AddDelete
                        }   
                }               
            });

            holder.chk.setChecked(itemChecked.get(cursor.getPosition()));

        }