使用ResourceCursorAdapter处理ListView中的循环复选框

时间:2012-02-24 19:53:37

标签: android android-listview

我正在将手机联系人数据加载到ListView中,该ListView将TextView和CheckBox作为一行。

我面临的问题是处理CheckBox,一旦我检查了ListView中的任何项目, 它被检查但是当我向下滚动listView项目得到automatically检查一组新的行时,这发生只是因为listview回收了这些东西,但我如何处理这个为复选框

我正在使用ResourceCursorAdapter并使用bindView和newView方法。

我看到他们说要存储复选框状态的几个主题,但它们是not for ResourceCursorAdapter,那么该方法将如何?

到目前为止,我尝试了based on RateListDemo of commonsware

 public View getView (final int position, View convertView, ViewGroup parent) {

    View row = super.getView(position, convertView, parent);
    ContactListItemCache holder=(ContactListItemCache)row.getTag();

    if (holder==null) { 
    holder=new ContactListItemCache(row);
    row.setTag(holder);

    /** I really don't know what to set over here **/
    CheckBox cbox=(CheckBox)row.findViewById(R.id.contactCheck);
        cbox.setOnClickListener( new OnClickListener(){
            @Override
            public void onClick(View v) {


                Log.d("Check check",position+"");

            }

        });

        /** I really don't know what to set over here too **/
        holder.selCheckBox =cbox;
        holder.selCheckBox.setTag(new Integer(position));

    }
return row;

}

这是我的ContactListItemCache

  final static class ContactListItemCache {
    public TextView nameView;
    public QuickContactBadge photoView;
    public CheckBox selCheckBox;
    public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
    public CharArrayBuffer nameMiddleBuffer = new CharArrayBuffer(128);
    public CharArrayBuffer nameFamilyBuffer = new CharArrayBuffer(128);

    /** Following Changes I have Made **/
    ContactListItemCache(){}
    ContactListItemCache(View base){

        selCheckBox = (CheckBox)base.findViewById(R.id.contactCheck);
       }
}

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题并想出了一个解决方法,虽然我不确定这是最好的方法。

我遵循了这个(相当不错的)系列教程http://www.vogella.de/articles/AndroidListView/article.html#overview_listview 并实施,包括第8节。“教程:域模型和行交互”

请注意,这不使用ResourceCursorAdapter。

从那里,我修改了getModel()函数和Model类本身。我更改了getModel()方法以返回与我的数据库中的数据匹配的模型列表。这是一些示例代码(大多数是从教程中复制的,带有示例修改)。请留意'//附加数据示例'评论。这显示了被修改以处理更多数据的位置(例如,如果您希望List项目显示的不仅仅是CheckBox和TextView)。

public class Model {

    private String name;
    private int exampleInt; // example of additional data
    private boolean selected;

    public Model(String name) {
        this.name = name;
        this.exampleInt= 0;
        selected = false;
    }

    public Model(String name, int exampleInt) {
        this.name = name;
        this.exampleInt= exampleInt;
        selected = false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // example of additional data
    public int getExampleInt() {
        return exampleInt;
    }

    public void setExampleInt(int i) {
        this.exampleInt = i;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

}

然后,在您的活动中,修改getModel()函数以使用数据库中的信息填充列表。我假装示例数据(exampleInt)保存在“exampleint”列中:

private List<Model> getModel() {
    //setContentView(R.layout.teamview);
    datasource.open();
    Cursor cursor = datasource.GetCursor();

    List<Model> list = new ArrayList<Model>();

    while ( cursor.moveToNext() ) {
        list.add( get( cursor.getString( cursor.getColumnIndex( "name" ) ),
                cursor.getInt(cursor.getColumnIndex("exampleint" ) ) ) );  // example of additional data
    }

    // Initially select one of the items
    //list.get(1).setSelected(true);
    datasource.close();
    return list;
}

如果你想要额外的exampleInt,你还必须修改get()函数,返回一个新的Model实例:

private Model get(String name, int example) {
    return new Model(name, example);
}

最后,在您的arrayadapter中(在教程中它是InteractiveArrayAdapter),更改ViewHolder以匹配您的列表项布局。在这个例子中,我将假装它被称为'youritemlayoutxml',并有一个额外的TextView(R.id.exampleint)来显示我们的新exampleInt。还要修改getView(...)函数以使用所需信息设置视图:

static class ViewHolder {
    protected TextView textName;
    protected TextView textExampleInt; // example of additional data
    protected CheckBox checkbox;
}


public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        view = inflator.inflate(R.layout.youritemlayoutxml, null);
        final ViewHolder viewHolder = new ViewHolder();
        viewHolder.textName = (TextView) view.findViewById(R.id.name);
        viewHolder.textExampleInt= (TextView) view.findViewById(R.id.exampleint);  // example of additional data
        viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkbox1);
        viewHolder.checkbox
                .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {
                        Model element = (Model) viewHolder.checkbox
                                .getTag();
                        element.setSelected(buttonView.isChecked());

                    }
                });
        view.setTag(viewHolder);
        viewHolder.checkbox.setTag(list.get(position));
    } else {
        view = convertView;
        ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
    }
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.textName.setText(list.get(position).getName());
    holder.textExampleInt.setText(Integer.toString(list.get(position).getExampleInt()));  // example of additional data
    holder.checkbox.setChecked(list.get(position).isSelected());
    return view;
}

我相信其他一切都不应该在教程中修改。

答案 1 :(得分:0)

commonsWare有一个很好的例子可以解决这个问题:

RateListDemo

希望这有帮助。