【发布时间】:2014-07-15 11:04:54
【问题描述】:
我正在开发一个使用 ListView 来显示用户及其个人资料的 android 应用程序。您可以在下面的图片中看到它的实际外观。可能有大量用户,所以我实现了延迟加载功能,一次加载四个用户。当应用程序启动时(列表中有 4 个用户),一切看起来都很好,但是在我向下滚动并加载接下来的四个用户后,发生了一些奇怪的事情。正如您在图像上看到的,每个用户都有自己的棋子,例如,其中一些人有眼镜,而另一些人没有。滚动后,似乎新加载的用户或其中一些用户也有眼镜,虽然他们不应该有。
http://pasteboard.co/1xs78l6C.png
我可以猜到问题的发生是因为适配器回收了视图。视图由许多图像组成,我认为在没有此功能(回收)的情况下实现适配器并不是一个好主意。另一方面,我对它没有很好的经验,我不知道应该注意哪里来防止这种行为。如有任何帮助或建议如何解决此问题,我将不胜感激。
在这里你可以看到我的适配器是什么样子的
public class UserAdapter extends BaseAdapter {
private final Context context;
private ArrayList<User> users;
private HashMap<String, Integer> resIds;
private final int[] slotIds = { R.id.imgRowSlot1, R.id.imgRowSlot2,
R.id.imgRowSlot3 };
public UserAdapter(Context context) {
this.context = context;
users = new ArrayList<User>();
resIds = new HashMap<String, Integer>(Config.init());
}
public void updateUsers(List<User> users) {
this.users = new ArrayList<User>(users);
notifyDataSetChanged();
}
@Override
public int getCount() {
return users.size();
}
@Override
public User getItem(int position) {
return users.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView txtFirstName;
TextView txtLastName;
ImageView imgSlot1;
ImageView imgSlot2;
ImageView imgSlot3;
ImageView imgHead;
ImageView imgGlasses;
ImageView imgTop;
ImageView imgBottom;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.user_row, parent, false);
txtFirstName = (TextView) convertView
.findViewById(R.id.txtFirstName);
txtLastName = (TextView) convertView.findViewById(R.id.txtLastName);
imgSlot1 = (ImageView) convertView.findViewById(R.id.imgRowSlot1);
imgSlot2 = (ImageView) convertView.findViewById(R.id.imgRowSlot2);
imgSlot3 = (ImageView) convertView.findViewById(R.id.imgRowSlot3);
imgHead = (ImageView) convertView
.findViewById(R.id.imgHead_adapter);
imgGlasses = (ImageView) convertView
.findViewById(R.id.imgGlasses_adapter);
imgTop = (ImageView) convertView.findViewById(R.id.imgTop_adapter);
imgBottom = (ImageView) convertView
.findViewById(R.id.imgBottom_adapter);
convertView.setTag(new ViewHolder(txtFirstName, txtLastName,
imgSlot1, imgSlot2, imgSlot3, imgHead, imgGlasses, imgTop,
imgBottom));
} else {
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
txtFirstName = viewHolder.txtFirstName;
txtLastName = viewHolder.txtLastName;
imgSlot1 = viewHolder.imgSlot1;
imgSlot2 = viewHolder.imgSlot2;
imgSlot3 = viewHolder.imgSlot3;
imgHead = viewHolder.imgHead;
imgGlasses = viewHolder.imgGlasses;
imgTop = viewHolder.imgTop;
imgBottom = viewHolder.imgBottom;
}
User user = getItem(position);
int[] slots = user.getSlots();
// name
txtFirstName.setText(user.getFirstName());
txtLastName.setText(user.getLastName());
// fruits
imgSlot1.setImageResource(MyDataController.fruits[slots[0]]);
imgSlot2.setImageResource(MyDataController.fruits[slots[1]]);
imgSlot3.setImageResource(MyDataController.fruits[slots[2]]);
FruitExtractor.setAlpha(convertView, slotIds, user);
// pawn head
if (user.getConsCounter() >= 2) {
imgHead.setImageResource(R.drawable.head_happy_noeyes);
} else if (user.getConsCounter() == 1) {
imgHead.setImageResource(R.drawable.head_indiferent_noeyes);
} else {
imgHead.setImageResource(R.drawable.head_sad_noeyes);
}
// glasses
if (user.getGlasses() != null) {
imgGlasses.setImageResource(resIds.get(user.getGlasses()
.getResIdName()));
}
// body
imgTop.setImageResource(resIds.get(user.getTop().getResIdName()));
imgBottom.setImageResource(resIds.get(user.getBottom().getResIdName()));
return convertView;
}
private static class ViewHolder {
public final TextView txtFirstName;
public final TextView txtLastName;
public final ImageView imgSlot1;
public final ImageView imgSlot2;
public final ImageView imgSlot3;
public final ImageView imgHead;
public final ImageView imgGlasses;
public final ImageView imgTop;
public final ImageView imgBottom;
public ViewHolder(TextView txtFirstName, TextView txtLastName,
ImageView imgSlot1, ImageView imgSlot2, ImageView imgSlot3,
ImageView imgHead, ImageView imgGlasses, ImageView imgTop,
ImageView imgBottom) {
this.txtFirstName = txtFirstName;
this.txtLastName = txtLastName;
this.imgSlot1 = imgSlot1;
this.imgSlot2 = imgSlot2;
this.imgSlot3 = imgSlot3;
this.imgHead = imgHead;
this.imgGlasses = imgGlasses;
this.imgTop = imgTop;
this.imgBottom = imgBottom;
}
}
public List<User> getUsers() {
return users;
}
}
【问题讨论】:
标签: android android-listview baseadapter