列表适配器中的 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);
}
我正在使用 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);
}