由List适配器中的getView提供的错误视图

时间:2016-07-07 21:55:24

标签: android listview android-viewholder

我正在使用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);
            }
        }
    }

}

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

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

创建活动后,一切似乎都没问题:

enter image description here

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

enter image description here

我做错了什么?

2 个答案:

答案 0 :(得分:4)

Android正在回收列表中的视图,并且设置图标“A”的视图作为参数传递给方法getView,当它不可见时。 解决方案是再次设置默认图标,如下所示:

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

答案 1 :(得分:2)

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

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