How do i prevent recycled ListView items from showing old content?

僤鯓⒐⒋嵵緔 提交于 2019-12-05 08:49:32

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!