带有Glide的Android listview-加载后位图加倍 [英] Android listview with Glide - doubled bitmaps after load

查看:74
本文介绍了带有Glide的Android listview-加载后位图加倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个android应用程序.我的片段之一包含一个显示好友列表的简单列表视图.每个朋友可以拥有自己的个人资料图片-由Glide库设置.当用户没有个人资料照片设置时,将显示默认图像.我的问题是,列表中的第一个元素每次都获得与在列表的最后一个元素(不是默认图片)中设置的图片相同的图片.我的意思显示在图片上:

I'm developing an android application. One of my fragments contains a simple listview showing friend list. Each friend can have its own profile image - it is set by the Glide library. When user has no profile pic set the default image is shown. My problem is, that every time, first element on the list gets the same picture which is set on the last element of the list which is not default picture. What i mean is shown on pic:

名称为 wiktor 的用户已设置个人资料图片,并且如您所见,第一个位置 bonzo 具有wiktor的个人资料图片(bonzo应该具有默认图片)

user with name wiktor has set profile picture and as you see the first position bonzo has wiktor's profile pic ( bonzo should have default pic )

删除用户表单列表也存在问题:

there is also a problem with deleting user form list:

如您所见,我从朋友列表中删除了 majka ,接下来的元素得到了她的照片.

as you see, i removed majka from friend list and next elements gets her picture.

默认配置文件图片是在可绘制对象的内部行布局xml中设置的.

The default profile picture is set in inside row layout xml from drawables.

这是我的列表视图适配器的代码:

Here is code of my listview adapter:

public class FriendsAdapter extends ArrayAdapter<FriendData> {

static class FriendHolder {

    TextView friendName;
    TextView friendRank;
    ImageView friendIcon;
    ImageButton deleteFriendBtn;
    ImageButton banFriendBtn;
}

private List<FriendData> list;

public FriendsAdapter(Context context, int resource, List<FriendData> objects) {

    super(context, resource, objects);
    list = objects;
}

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {

    final FriendData element = getItem(position);
    final FriendHolder viewHolder;
    if (convertView == null) {

        viewHolder = new FriendHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.friend_layout, parent, false);
        viewHolder.friendIcon = (ImageView) convertView.findViewById(R.id.friendIcon);
        viewHolder.friendName = (TextView) convertView.findViewById(R.id.friendName);
        viewHolder.friendRank = (TextView) convertView.findViewById(R.id.friendRank);
        viewHolder.deleteFriendBtn = (ImageButton) convertView.findViewById(R.id.deleteFriendBtn);
        viewHolder.banFriendBtn = (ImageButton) convertView.findViewById(R.id.banFriendBtn);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (FriendHolder) convertView.getTag();
    }

    if (element.getPhoto() != null) {

        String photo = S3ImageHandler.SMALL_PROFILE_ICON_PREFIX + element.getPhoto();
        String url = String.format(S3ImageHandler.AMAZON_PROFILE_DOWNLOAD_LINK, photo);
        Glide.with(getContext())
                .load(url)
                .asBitmap()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .placeholder(R.drawable.user_small)
                .into(new BitmapImageViewTarget(viewHolder.friendIcon) {
                    @Override
                    protected void setResource(Bitmap resource) {

                        RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getContext().getResources(), resource);
                        circularBitmapDrawable.setCircular(true);
                        viewHolder.friendIcon.setImageDrawable(circularBitmapDrawable);
                    }
                });
    }

    viewHolder.friendName.setText(element.getId());
    viewHolder.friendRank.setText(String.format("%s %d", getContext().getString(R.string.text_rank), element.getRank()));
    viewHolder.deleteFriendBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
            confirmDelete(element, position, parent);
        }
    });
    viewHolder.banFriendBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            confirmBan(element, position, parent);
        }
    });

    return convertView;
}

从好友列表中删除用户:

removing user from friend list:

        remove(element);
        notifyDataSetChanged();

你们中有人看到我做错了吗?我将非常感谢您的帮助.谢谢:)

does any of you see what i do wrong ? i would be very grateful for some help. thank you :)

推荐答案

您要恢复列表项(根据回收者视图"的定义),这意味着如果将图像设置为某项并且您没有清除它,则图像将保留在那里.因此,即使setText更改了标签,也不会触摸viewHolder.friendIcon.解决方法非常简单:

You're resuing list items (by definition of recycler view) which means that if an image was set to an item and you don't clear it, the image will remain there. So even though setText changes the labels viewHolder.friendIcon is not touched. The fix is really simple:

if (element.getPhoto() != null) {
    Glide.with(getContext())...
} else {
    Glide.clear(viewHolder.friendIcon); // tell Glide that it should forget this view
    viewHolder.friendIcon.setImageResource(R.drawable.user_small); // manually set "unknown" icon
}

还要从xml中删除drawable,或者至少更改为tools:src,这将有助于减少充气时间;无论如何,该值都会被Glide覆盖.

Also remove the drawable from the xml, or at least change to tools:src which will help reducing the inflation time; the value is overwritten by Glide every time anyway.

为降低复杂性,有另一种选择:

To reduce complexity there's an alternative:

class FriendData {
    // if you can't modify this class you can also put it in a `static String getPhotoUrl(Element)` somewhere
    public void String getPhotoUrl() {
        if (this.getPhoto() == null) return null;
        String photo = S3ImageHandler.SMALL_PROFILE_ICON_PREFIX + this.getPhoto();
        String url = String.format(S3ImageHandler.AMAZON_PROFILE_DOWNLOAD_LINK, photo);
        return url;
    }
}

,然后将整个if (element.getPhoto() != null) {...}替换为:

Glide.with(getContext())
     .load(element.getPhotoUrl()) // this may be null --\
     .asBitmap() //                                     |
     .diskCacheStrategy(DiskCacheStrategy.ALL) //       |
     .placeholder(R.drawable.user_small) //             |
     .fallback(R.drawable.user_small) // <--------------/
     .into(new BitmapImageViewTarget(viewHolder.friendIcon) { ... })
;

这也将导致正确的行为,因为即使没有图像URL,Glide也会照顾一些设置,请参阅JavaDoc或fallback的来源.

This will also result in proper behavior because even though there's no image url Glide will take care of setting something, see JavaDoc or source of fallback.

作为旁注,还可以考虑使用 CircleCrop .除了缓存优势外,它还支持GIF,因为您可以删除.asBitmap()和自定义目标.

As a sidenote also consider using CircleCrop. Aside from caching benefits it would also support GIFs because you can remove the .asBitmap() and the custom target.

这篇关于带有Glide的Android listview-加载后位图加倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆