我如何美元,显示旧的内容p $ pvent回收的ListView项目? [英] How do i prevent recycled ListView items from showing old content?

查看:109
本文介绍了我如何美元,显示旧的内容p $ pvent回收的ListView项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用自定义ResourceCursorAdapter显示一个TextView和一个CheckBox一个ListView。 TextView的和CheckBox从游标得到他们的状态。我一直有与它的几个问题,最近一次是,当我滚动某些行是因为旧的TextViews文本和一些复选框被选中时,他们不应该。我添加了一个日志行,看看发生了什么事情,这只是我感到困惑了。

  @覆盖
公共无效bindView(视图V,上下文CTX,光标C){
    ViewHolder支架=(ViewHolder)v.getTag();holder.tv.setText(holder.tvText);
holder.cb.setChecked(holder.checked);
Log.d(TAG,在bindView,ROWID:+ holder.rowId +经文:+ holder.tvText);
}

  @覆盖
公共查看NewView的(上下文CTX,光标C,VG的ViewGroup){    视图V = li.inflate(布局,VG,FALSE);
    ViewHolder持有人;    持有人=新ViewHolder();
    holder.tv =(TextView中)v.findViewById([0]);
    holder.tvText = c.getString(c.getColumnIndex(从[0]));
    holder.cb =(复选框)v.findViewById([1]);
    holder.rowId = c.getLong(c.getColumnIndex(从[2]));
    holder.checked =(c.getString(c.getColumnIndexOrThrow(从[1]))。等于(N))?
            假:真实的;
    holder.cb.setOnClickListener(新OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            查看rowView =((查看)v.getParent());
            ViewHolder支架=(ViewHolder)rowView.getTag();            holder.checked =(holder.checked ==假)?真假;            smDb.setMemorized(holder.rowId);
            rowView.setTag(保持器);
            Log.d(TAG复选框,点击+ holder.rowId);
        }});
    Log.d(TAG,在NewView的,ROWID:+ holder.rowId);
    v.setTag(保持器);
    返回伏;
}

 静态类ViewHolder {
    TextView的电视;
    串tvText;
    复选框CB;
    布尔检查;
    龙ROWID;
}

日志输出

 在NewView的,ROWID:26
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在NewView的,ROWID:27
在bindView,ROWID:27经文:马太福音6:24
在NewView的,ROWID:28
在bindView,ROWID:28经文:马太福音16:15-9
在NewView的,ROWID:29
在bindView,ROWID:29经文:马太福音25:40
在NewView的,ROWID:30
在bindView,ROWID:30经文:路加福音24:36-9
在NewView的,ROWID:31
在bindView,ROWID:31经文:约翰福音3:5
在NewView的,ROWID:32
在bindView,ROWID:32经文:约翰7:17
在NewView的,ROWID:33
在bindView,ROWID:33经文:约翰福音10:16
在NewView的,ROWID:34
在bindView,ROWID:34经文:约翰福音14:15
在NewView的,ROWID:26
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6


解决方案

这是造成您的问题的看法回收。

我不知道这是处理它的方式平稳的,但是这是我做到了。我做了一个数组来保存我的按钮状态信息,然后用它在我的getView方法,以确保状态保持,即使元素熄灭屏幕。

从我的项目中我有在每一行按键,可以有几个州(文本和彩色)的列表适配器的一个例子:

 公共类ButtonCursorAdapter扩展SimpleCursorAdapter {
    私人光标C; //在鼠标经过
    私人上下文的背景下;
    私人活动活动;
    公共静态的String [] atdState; // String数组来保存按钮状态
    公共静态的String [] atdRow; //匹配的字符串数组来保存分贝ROWID    公共ButtonCursorAdapter(上下文的背景下,INT布局,光标C,
                    的String []从,INT []到){
            超(背景下,布局,C,从,到);
            this.c = C;
            this.context =背景;
            this.activity =(活动)范围内;
            atdState =新的String [c.getCount()]; //初始化按钮状态数组
            atdRow =新的String [c.getCount()]; //初始化数据库ROWID阵列
            c.moveToFirst();
            INT I = 0;
            而(c.isAfterLast()== FALSE){
                    如果(c.getString(3)== NULL){//如果状态为空,设置为
                            atdState [I] =;
                    }其他{
                            atdState [I] = c.getString(3); //设置状态,状态保存在数据库
                    }
                    atdRow [I] = c.getString(0); //从数据库设置ROWID
                    我++;
                    c.moveToNext();
            }
    }    @覆盖
    公共查看getView(INT位置,查看convertView,父母的ViewGroup){
            如果(convertView == NULL)
                    convertView = View.inflate(背景下,
                                    R.layout.listlayoutdoublebutton,NULL);
            最终诠释POS =位置;
            查看排= convertView;
            c.moveToPosition(位置);
            TextView的第一=(TextView中)convertView.findViewById(R.id.ListItem1);
            去年的TextView =(TextView中)convertView.findViewById(R.id.ListItem2);
            按钮atdButton =(按钮)convertView.findViewById(R.id.attendbutton);
            first.setText(c.getString(1));
            last.setText(c.getString(2));
            atdButton.setText(atdState [位置]); //设置按钮状态
            如果(atdState [位置] .equals(P)){//根据状态着色按钮
                    atdButton.getBackground()。setColorFilter(0xFF00FF00,
                                    PorterDuff.Mode.MULTIPLY);
            }否则如果(atdState [位置] .equals(T)){
                    atdButton.getBackground()。setColorFilter(0xFFFFFF00,
                                    PorterDuff.Mode.MULTIPLY);
            }否则如果(atdState [位置] .equals(E)){
                    atdButton.getBackground()。setColorFilter(0xFFFF6600,
                                    PorterDuff.Mode.MULTIPLY);
            }否则如果(atdState [位置] .equals(U)){
                    atdButton.getBackground()。setColorFilter(0xFFFF0000地址,
                                    PorterDuff.Mode.MULTIPLY);
            }其他{
                    。atdButton.getBackground()clearColorFilter();
            }
            atdButton.setFocusable(真);
            atdButton.setClickable(真);            atdButton.setOnClickListener(新OnClickListener(){
                    @覆盖
                    公共无效的onClick(查看视图){
                            按钮atdButton =(按钮)查看
                                            .findViewById(R.id.attendbutton);
                            。字符串测试= atdButton.getText()的toString();
                            如果(test.equals()){
                                    atdButton.setText(P);
                                    atdState [POS] =P;
                                    atdButton.getBackground()。setColorFilter(0xFF00FF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            }否则如果(test.equals(P)){
                                    atdButton.setText(T);
                                    atdState [POS] =T;
                                    atdButton.getBackground()。setColorFilter(0xFFFFFF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            }否则如果(test.equals(T)){
                                    atdButton.setText(E);
                                    atdState [POS] =E;
                                    atdButton.getBackground()。setColorFilter(0xFFFF6600,
                                                    PorterDuff.Mode.MULTIPLY);
                            }否则如果(test.equals(E)){
                                    atdButton.setText(U);
                                    atdState [POS] =U;
                                    atdButton.getBackground()。setColorFilter(0xFFFF0000地址,
                                                    PorterDuff.Mode.MULTIPLY);
                            }否则如果(test.equals(U)){
                                    atdButton.setText(P);
                                    atdState [POS] =P;
                                    atdButton.getBackground()。setColorFilter(0xFF00FF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            }
                    }
            });
            返回(行);
    }

}

在哪里我使用的setText和着色我的按钮,你会想setChecked或一些这样的,但希望这将指向你在正确的方向。

I'm working on a ListView that uses a custom ResourceCursorAdapter to display a TextView and a CheckBox. The TextView and CheckBox get their state from the Cursor. I've been having a few problems with it, the most recent being that when I scroll some of the rows have text from old TextViews and some CheckBoxes are selected when they shouldn't be. I've added a log line to see what's going on and that's just confused me more.

@Override
public void bindView(View v, Context ctx, Cursor c) {
    ViewHolder holder = (ViewHolder)v.getTag();

holder.tv.setText(holder.tvText);           
holder.cb.setChecked(holder.checked);
Log.d(TAG, "in bindView, rowId:" + holder.rowId + " Scripture:" + holder.tvText);   
}

.

@Override
public View newView(Context ctx, Cursor c, ViewGroup vg){       

    View v = li.inflate(layout, vg, false);
    ViewHolder holder;

    holder = new ViewHolder();
    holder.tv = (TextView)v.findViewById(to[0]);
    holder.tvText = c.getString(c.getColumnIndex(from[0]));
    holder.cb = (CheckBox)v.findViewById(to[1]);
    holder.rowId = c.getLong(c.getColumnIndex(from[2]));
    holder.checked = (c.getString(c.getColumnIndexOrThrow(from[1])).equals("n")) ?
            false : true;
    holder.cb.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            View rowView = ((View)v.getParent());
            ViewHolder holder = (ViewHolder)rowView.getTag();

            holder.checked = (holder.checked == false) ? true : false;

            smDb.setMemorized(holder.rowId);
            rowView.setTag(holder);
            Log.d(TAG, "check box clicked: " + holder.rowId);
        }});
    Log.d(TAG, "in newView, rowId:" + holder.rowId);
    v.setTag(holder);


    return v;       
}

.

static class ViewHolder {
    TextView tv;
    String tvText;
    CheckBox cb;
    boolean checked;
    Long rowId;
}

The Log output

in newView, rowId:26
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in newView, rowId:27
in bindView, rowId:27 Scripture:Matthew 6:24
in newView, rowId:28
in bindView, rowId:28 Scripture:Matthew 16:15-9
in newView, rowId:29
in bindView, rowId:29 Scripture:Matthew 25:40
in newView, rowId:30
in bindView, rowId:30 Scripture:Luke 24:36-9
in newView, rowId:31
in bindView, rowId:31 Scripture:John 3:5
in newView, rowId:32
in bindView, rowId:32 Scripture:John 7:17
in newView, rowId:33
in bindView, rowId:33 Scripture:John 10:16
in newView, rowId:34
in bindView, rowId:34 Scripture:John 14:15
in newView, rowId:26
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6

解决方案

It's the view recycling that's causing your issue.

I'm not sure this is the smoothest way of handling it, but this is how I did it. I made an array to hold my button state information and then used it in my getView method to make sure the state is maintained even when an element goes off-screen.

Example from one of my projects where I have a list adapter with buttons on each row that can have several states (text and color):

public class ButtonCursorAdapter extends SimpleCursorAdapter {
    private Cursor c;                       // Passed in cursor
    private Context context;
    private Activity activity;
    public static String[] atdState;       // String array to hold button state
    public static String[] atdRow;         // Matching string array to hold db rowId

    public ButtonCursorAdapter(Context context, int layout, Cursor c,
                    String[] from, int[] to) {
            super(context, layout, c, from, to);
            this.c = c;
            this.context = context;
            this.activity = (Activity) context;
            atdState = new String[c.getCount()];  // initialize button state array
            atdRow = new String[c.getCount()];    // initialize db rowId array
            c.moveToFirst();
            int i = 0;
            while (c.isAfterLast() == false) {
                    if (c.getString(3) == null) {  // if state is null, set to " "
                            atdState[i] = " ";
                    } else {
                            atdState[i] = c.getString(3);  // set state to state saved in db
                    }
                    atdRow[i] = c.getString(0);     // set the rowId from the db
                    i++;
                    c.moveToNext();
            }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null)
                    convertView = View.inflate(context,
                                    R.layout.listlayoutdoublebutton, null);
            final int pos = position;
            View row = convertView;
            c.moveToPosition(position);
            TextView first = (TextView) convertView.findViewById(R.id.ListItem1);
            TextView last = (TextView) convertView.findViewById(R.id.ListItem2);
            Button atdButton = (Button) convertView.findViewById(R.id.attendbutton);
            first.setText(c.getString(1));
            last.setText(c.getString(2));
            atdButton.setText(atdState[position]);  // set the button state
            if (atdState[position].equals("P")) {   // colorize the button depending on state
                    atdButton.getBackground().setColorFilter(0xFF00FF00,
                                    PorterDuff.Mode.MULTIPLY);
            } else if (atdState[position].equals("T")) {
                    atdButton.getBackground().setColorFilter(0xFFFFFF00,
                                    PorterDuff.Mode.MULTIPLY);
            } else if (atdState[position].equals("E")) {
                    atdButton.getBackground().setColorFilter(0xFFFF6600,
                                    PorterDuff.Mode.MULTIPLY);
            } else if (atdState[position].equals("U")) {
                    atdButton.getBackground().setColorFilter(0xFFFF0000,
                                    PorterDuff.Mode.MULTIPLY);
            } else {
                    atdButton.getBackground().clearColorFilter();
            }
            atdButton.setFocusable(true);
            atdButton.setClickable(true);

            atdButton.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                            Button atdButton = (Button) view
                                            .findViewById(R.id.attendbutton);
                            String test = atdButton.getText().toString();
                            if (test.equals(" ")) {
                                    atdButton.setText("P");
                                    atdState[pos] = "P";
                                    atdButton.getBackground().setColorFilter(0xFF00FF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            } else if (test.equals("P")) {
                                    atdButton.setText("T");
                                    atdState[pos] = "T";
                                    atdButton.getBackground().setColorFilter(0xFFFFFF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            } else if (test.equals("T")) {
                                    atdButton.setText("E");
                                    atdState[pos] = "E";
                                    atdButton.getBackground().setColorFilter(0xFFFF6600,
                                                    PorterDuff.Mode.MULTIPLY);
                            } else if (test.equals("E")) {
                                    atdButton.setText("U");
                                    atdState[pos] = "U";
                                    atdButton.getBackground().setColorFilter(0xFFFF0000,
                                                    PorterDuff.Mode.MULTIPLY);
                            } else if (test.equals("U")) {
                                    atdButton.setText("P");
                                    atdState[pos] = "P";
                                    atdButton.getBackground().setColorFilter(0xFF00FF00,
                                                    PorterDuff.Mode.MULTIPLY);
                            }
                    }
            });
            return (row);
    }

}

Where I use setText and colorize my button you would want to setChecked or some such, but hopefully this will point you in the right direction.

这篇关于我如何美元,显示旧的内容p $ pvent回收的ListView项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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