我正在开发一个Android应用程序。我的一个片段包含一个显示好友列表的简单列表视图。每个朋友都可以拥有自己的个人资料图片 - 由Glide图书馆设置。当用户没有设置配置文件时,将显示默认图像。我的问题是,每次,列表中的第一个元素获得相同的图片,该图片在列表的最后一个元素上设置,而不是默认图片。我的意思如图所示:
名为 wiktor 的用户设置了个人资料图片,当您看到第一个位置 bonzo 有wiktor的个人资料照片(bonzo应该有默认照片)
删除用户表单列表时也存在问题:
如你所见,我从朋友列表中删除了 majka ,然后下一个元素获取了她的照片。
默认配置文件图片在drawables的内部行布局xml中设置。
以下是我的listview适配器的代码:
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;
}
从朋友列表中删除用户:
remove(element);
notifyDataSetChanged();
你们有没有看到我做错了什么?我会非常感谢你的帮助。谢谢你:))
答案 0 :(得分:8)
您正在恢复列表项(根据回收站视图的定义),这意味着如果图像设置为某个项而您没有清除它,则图像将保留在那里。因此,即使setText
更改,标签viewHolder.friendIcon
也不会被触及。修复非常简单:
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都会覆盖这个值。
为了降低复杂性,还有另一种选择:
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) { ... })
;
这也会导致正确的行为,因为即使没有图像网址,Glide也会负责设置内容,请参阅JavaDoc或fallback
的来源。
作为旁注,还要考虑使用CircleCrop
。除了缓存优势之外,它还支持GIF,因为您可以删除.asBitmap()
和自定义目标。