手柄内有ResourceCursorAdapter的ListView回收复选框 [英] handle recycled checkbox inside ListView with ResourceCursorAdapter

查看:133
本文介绍了手柄内有ResourceCursorAdapter的ListView回收复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我加载电话联系到的数据有一个TextView和一个CheckBox作为行一个ListView。

我现在面临的问题是在处理复选框,​​一旦我检查的任何项目在ListView,
它被选中,但是当我向下滚动ListView的项目获得检查自动一组新的行,这只是因为ListView中回收的东西happeing,但我怎么能处理这一个对于复选框

我使用 ResourceCursorAdapter 和使用bindView和NewView的方法。

我看到他们说来存储复选框的状态的线程数,但它们是不是ResourceCursorAdapter ,所以如何将这种方法?

到目前为止,我尝试以下<一个href=\"https://github.com/commonsguy/cw-android/blob/master/FancyLists/RateList/src/com/commonsware/android/fancylists/six/RateListDemo.java\"相对=nofollow> 基于commonsware的RateListDemo

 公共查看getView(最终诠释的立场,观点convertView,父母的ViewGroup){    查看排= super.getView(位置,convertView,父母);
    ContactListItemCache支架=(ContactListItemCache)row.getTag();    如果(持有者== NULL){
    持有人=新ContactListItemCache(行);
    row.setTag(保持器);    / **我真的不知道该怎么设置在这里** /
    复选框CBOX =(复选框)row.findViewById(R.id.contactCheck);
        cbox.setOnClickListener(新OnClickListener(){
            @覆盖
            公共无效的onClick(视图v){
                Log.d(检查检查位置+);            }        });        / **我真的不知道如何设置在这里太** /
        holder.selCheckBox = CBOX;
        holder.selCheckBox.setTag(新的整数(位置));    }
返回行;}

这是我ContactListItemCache

 最终静态类ContactListItemCache {
    公众的TextView nameView;
    公共QuickContactBadge PhotoView中;
    公共复选框selCheckBox;
    公众的CharArrayBuffer nameBuffer =新的CharArrayBuffer(128);
    公众的CharArrayBuffer nameMiddleBuffer =新的CharArrayBuffer(128);
    公众的CharArrayBuffer nameFamilyBuffer =新的CharArrayBuffer(128);    / **以下更改我已经** /
    ContactListItemCache(){}
    ContactListItemCache(查看基地){        selCheckBox =(复选框)base.findViewById(R.id.contactCheck);
       }
}


解决方案

我有一个类似的问题,用一种变通方法来了,虽然我不知道这是做的最好的方式。

我跟着这个(相当不错)系列教程的 HTTP:// WWW。 vogella.de/articles/AndroidListView/article.html#overview_listview
实施直至并包括第8章教程:领域模型和行互动

注意,这不使用ResourceCursorAdapter

从那里,我修改了getModel()函数和模型类本身。我改变了getModel()方法返回的从我的数据库匹配数据模型的列表。下面是一些例子code(从例如修改教程最复制)。当心征求意见的附加数据//例如。这说明被修改的地方处理更多的数据(如果你希望你的列表项显示的不仅仅是一个CheckBox和TextView的例如更多)。

 公共类模式{    私人字符串名称;
    私人诠释exampleInt; //例如附加数据
    选择私人布尔;    公共模型(字符串名称){
        this.name =名称;
        this.exampleInt = 0;
        选择= FALSE;
    }    公共模型(字符串名称,诠释exampleInt){
        this.name =名称;
        this.exampleInt = exampleInt;
        选择= FALSE;
    }    公共字符串的getName(){
        返回名称;
    }    公共无效setname可以(字符串名称){
        this.name =名称;
    }    //例如附加数据
    公众诠释getExampleInt(){
        返回exampleInt;
    }    公共无效setExampleInt(int i)以{
        this.exampleInt = I;
    }    公共布尔isSelected(){
        返回所选择的;
    }    公共无效的setSelected(布尔选择){
        this.selected =选择;
    }}

然后,在你的活动,修改getModel()函数来填充与数据库中的信息列表。我是pretending示例数据(exampleInt)在列exampleint举行:

 私人列表&LT;模型与GT; getModel(){
    //setContentView(R.layout.teamview);
    datasource.open();
    光标光标= datasource.GetCursor();    清单&LT;模型与GT;名单=新的ArrayList&LT;模型与GT;();    而(cursor.moveToNext()){
        list.add(获得(cursor.getString(cursor.getColumnIndex(名称))
                cursor.getInt(cursor.getColumnIndex(exampleint)))); //例如附加数据
    }    //最初选择的项目之一
    //list.get(1).setSelected(true);
    datasource.close();
    返回列表;
}

您将不得不修改的get()函数以及它返回一个新的Model实例,如果你想额外的exampleInt:

 私人模型中获取(字符串名称,诠释为例){
    返回新的型号(名称,例如);
}

最后,在arrayadapter(在本教程中它是InteractiveArrayAdapter),改变ViewHolder以匹配您的列表项的布局。在这个例子中,我会pretend这就是所谓的'youritemlayoutxml,并有一个额外的TextView(R.id.exampleint),以显示我们的新exampleInt。还修改getView(...)函数来设置视图的所需资料:

 静态类ViewHolder {
    保护的TextView textName;
    保护的TextView textExampleInt; //例如附加数据
    保护复选框复选框;
}
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
    查看查看= NULL;
    如果(convertView == NULL){
        LayoutInflater充气= context.getLayoutInflater();
        鉴于= inflator.inflate(R.layout.youritemlayoutxml,NULL);
        最后ViewHolder viewHolder =新ViewHolder();
        viewHolder.textName =(TextView中)view.findViewById(R.id.name);
        viewHolder.textExampleInt =(TextView中)view.findViewById(R.id.exampleint); //例如附加数据
        viewHolder.checkbox =(复选框)view.findViewById(R.id.checkbox1);
        viewHolder.checkbox
                .setOnCheckedChangeListener(新CompoundButton.OnCheckedChangeListener(){                    公共无效onCheckedChanged(CompoundButton buttonView,
                            布尔器isChecked){
                        模型元素=(模型)viewHolder.checkbox
                                .getTag();
                        element.setSelected(buttonView.isChecked());                    }
                });
        view.setTag(viewHolder);
        viewHolder.checkbox.setTag(list.get(位置));
    }其他{
        鉴于= convertView;
        ((ViewHolder)view.getTag())checkbox.setTag(list.get(位置))。
    }
    ViewHolder支架=(ViewHolder)view.getTag();
    holder.textName.setText(list.get(位置).getName());
    holder.textExampleInt.setText(Integer.toString(list.get(位置).getExampleInt())); //例如附加数据
    holder.checkbox.setChecked(list.get(位置).isSelected());
    返回视图。
}

我认为一切应该从教程修改。

i am loading Phone Contact Data into a ListView which has a TextView and a CheckBox as a row.

the problem i am facing is in handling CheckBox , once i check on any item in a ListView , it gets checked but when i scroll down the listView items gets check automatically for a new set of rows, this is happeing just because listview recycled the stuff but how i can handle this one for checkbox

i am using ResourceCursorAdapter and using bindView and newView methods.

i saw few threads in which they said to store the state of checkbox but they are not for ResourceCursorAdapter , so how will be the approach ?

so far i tried following 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;

}

Here is my 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);
       }
}

解决方案

I had a similar problem and came up with a workaround, although I'm not sure this is the best way to do it.

I followed this (rather good) series of tutorials http://www.vogella.de/articles/AndroidListView/article.html#overview_listview and implemented up to and including section 8. "Tutorial: Domain Model and Rows interaction"

Note that this doesn't use ResourceCursorAdapter.

From there, I modified the getModel() function and the Model class itself. I changed the getModel() method to return a list of models that match the data from my database. Here's some example code (most copied from the tutorial with example modifications). Look out for the '// example of additional data' comments. This shows the places that were modified to handle more data (if you want your List items to display more than just a CheckBox and TextView for example).

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

}

Then, in your activity, modify the getModel() function to fill the list with the information from your database. I'm pretending the example data (exampleInt) is held in the column "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;
}

You'll have to modify the get() function as well which returns a new Model instance if you want the additional exampleInt:

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

Finally, in your arrayadapter (in the tutorial it is the InteractiveArrayAdapter), change the ViewHolder to match your list item layout. In this example I'll pretend it's called 'youritemlayoutxml', and has an additional TextView (R.id.exampleint) to display our new exampleInt. Also modify the getView(...) function to set up the view with the required information:

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

I believe everything else should be unmodified from the tutorial.

这篇关于手柄内有ResourceCursorAdapter的ListView回收复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆