列表适配器中的 getView 传递的错误视图

Wrong view delivered by getView in List adapter

我正在使用 BaseAdapter 和 ViewHolder 模式显示 ListView。

public class ListViewActivity extends AppCompatActivity {
    private String[] letters = {"A", "B", "C", "D",
            "E", "F", "G", "H", "I", "J", "K", "L",
            "M", "N", "O","P", "Q"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_lv);

        final ListView listView = (ListView) findViewById(R.id.listView);

        listView.setAdapter(new TestBaseAdapter(this, letters));
    }

    class TestBaseAdapter extends BaseAdapter {
        private Context context;
        private String[] values;
        private LayoutInflater inflater;
        public TestBaseAdapter(Context context, String[] values) {
            this.context = context;
            this.values = values;
            this.inflater = LayoutInflater.from(this.context);
        }

        @Override
        public int getCount() {
            return values.length;
        }

        @Override
        public Object getItem(int position) {
            return values[position];

        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            MyViewHolder myViewHolder;

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.lv_layout, parent, false);
                myViewHolder = new MyViewHolder(convertView);
                convertView.setTag(myViewHolder);
            } else {
                myViewHolder = (MyViewHolder) convertView.getTag();
            }

            myViewHolder.title.setText((String)getItem(position));
            if (((String)getItem(position)).equals("A")) {
                myViewHolder.icon.setImageResource(R.drawable.custom_icon);
            }

            return convertView;
        }

        private class MyViewHolder {
            TextView title;
            ImageView icon;

            public MyViewHolder(View item) {
                title = (TextView) item.findViewById(R.id.label);
                icon = (ImageView) item.findViewById(R.id.logo);
            }
        }
    }

}

代码只是在列表视图中显示数组的内容,其中每一行都包含数组中的一个项目,但如果项目值为"A",则行显示显示不同的图标。该条件在 getView(...) 方法的这一部分进行:

...
if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
}
...

创建 activity 后,一切似乎都正常:

但是当我向下滚动 listView 时,A 字母的图标随机显示在与 A 不同的字母上。

我做错了什么?

Android 正在回收列表中的视图,您设置图标 "A" 的视图在不可见时作为参数传递给方法 getView . 解决方法是重新设置默认图标,像这样:

if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
} else {
    myViewHolder.icon.setImageResource(/*your default image*/);
}

您必须更新所有视图的图标(不仅是带有字母 "A" 的视图)。

if (((String)getItem(position)).equals("A")) {
    myViewHolder.icon.setImageResource(R.drawable.custom_icon);
} else {
    myViewHolder.icon.setImageResource(R.drawable.DEFAULT_ICON_ID);
}