ListView回收视图功能会影响列表中的其他项目

时间:2014-07-15 11:04:55

标签: android android-listview baseadapter

我正在开发一个Android应用程序,它使用ListView来显示用户及其配置文件。您可以在下面的图片中看到它的实际外观。有可能拥有大量用户,因此我实现了延迟加载功能,可以在一轮中加载四个用户。当应用程序启动时(列表中有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;
    }
}

1 个答案:

答案 0 :(得分:1)

    // glasses
    if (user.getGlasses() != null) {
        imgGlasses.setImageResource(resIds.get(user.getGlasses()
                .getResIdName()));
    }else{
         //there is no else statement to clear the previous glasses
         //you can do something like this
         imgGlasses.setImageResource(android.R.color.transparent);
    }