【问题标题】:Checkbox listener in ListView with CursorAdapter带有 CursorAdapter 的 ListView 中的复选框侦听器
【发布时间】:2012-11-14 00:51:53
【问题描述】:

我有一个与this post 非常相似的问题。在我的 ListView 的每一行中,我都有一个带有侦听器的复选框。侦听器更新数据库行。

@Override
public void bindView(View v, Context context, Cursor c) {
    TextView tvA = (TextView) v.findViewById(R.id.adi_tv_activity);
    CheckBox cb = (CheckBox) v.findViewById(R.id.adi_cbox);
    tvA.setText(c.getString(c.getColumnIndex("name")));
    final long id = c.getLong(c.getColumnIndex("_id"));
    final Context ctx = context;
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            ObjDBF dbf = new ObjDBF(ctx); //Object thet update db
            if(isChecked) {
                dbf.tbActivitiesUpdateState(id, true);  
            } else {   
                dbf.tbActivitiesUpdateState(id, false);     
            }
        }               
    });
    if (c.getBoolean(c.getColumnIndex("state"))) {
        cb.setChecked(true);
    } else {
        cb.setChecked(false);
    }
}

我有 2 个问题。

  1. 滚动问题。移动列表时,我失去了从屏幕上消失的行的复选框状态。
  2. 每当我使用 setChecked 时,都会调用侦听器,从而导致新的数据库更新。

为了解决滚动问题,我想在每次更新数据库时使用 adapter.changeCursor,但对于第二个问题,它会导致循环。

我也尝试在上面链接帖子的第二个答案中使用数组,但它使用方法 getView od 适配器,我有一个 cursorAdapter 并在 newView 和 bindView 中工作

我该如何解决这个问题?

编辑:auselen 解决方案有效,但它创建和破坏了很多听众,还有其他更有效的解决方案吗?

【问题讨论】:

  • 如果在设置 CheckedChange 监听器之前移动“if block”会发生什么?要摆脱旧的侦听器,您可能必须执行类似 setOnCheckedChangeListener(null) -> setChecked -> setOnCheckedChangeListener(new Listener)
  • 有效!!!谢谢。如果您在答案中转换评论,我接受

标签: android listview checkbox android-cursoradapter


【解决方案1】:

为避免在侦听器上触发回调,您应该通过cb.setOnCheckedChangeListener(null) 取消注册现有的回调,然后设置cb.setChecked(c.getBoolean(c.getColumnIndex("state"))),然后再次设置cb.setOnCheckedChangeListener()

但是,您应该想出一个更好的方法来使用 OnCheckedChangeListener,因为您最终会创建超出需要的侦听器。

【讨论】:

    【解决方案2】:
    private SparseBooleanArray bolarray;
    public class ViewHolder{
            CheckBox checked_displayName;
            int contact_id;
            String displayName;
            boolean isChecked=false;
        }
    
    public void bindView(View v, Context context, Cursor cursor) 
    {
    
    ViewHolder viewHolder=new ViewHolder();
    
    viewHolder.checked_displayName=(CheckBox) 
    v.findViewById(R.id.checked_displayName);
    
    viewHolder.displayName=cursor.getString(cursor.getColumnIndex(PROJECTION[0]));
    
    viewHolder.checked_displayName.setText(viewHolder.displayName);
    
    viewHolder.checked_displayName.setTag(viewHolder);
    
    if(!bolarray.get(viewHolder.contact_id)){
                bolarray.put(viewHolder.contact_id, false);
                viewHolder.checked_displayName.setChecked(false);
                viewHolder.isChecked=false;
            }else{
    
                bolarray.put(viewHolder.contact_id, true);
                viewHolder.checked_displayName.setChecked(true);
                viewHolder.isChecked=true;
            }   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 2014-05-27
      • 2012-10-30
      • 2011-06-30
      • 2015-10-20
      • 2018-12-26
      • 1970-01-01
      相关资源
      最近更新 更多