[英]Glide and RecyclerView - Images messed up
我正在尝试使用ImageViews创建一个RecyclerView。 这是我得到的:
如您所见,所有歌手封面都被弄乱了,顺序错误。 如果我滚动或重新加载,各自的图像可能会改变。
这是我的适配器onBindViewHolder:
public class ArtistsAdapter extends RecyclerView.Adapter<ArtistViewHolder> implements ListPreloader.PreloadModelProvider {
private static final String TAG = ArtistsAdapter.class.getSimpleName();
private final LayoutInflater mInflater;
private final GlideRequest<Bitmap> fullRequest;
ArtistsAdapter(Context context) {
this.mContext = context;
this.artists = new ArrayList<>();
this.mInflater = LayoutInflater.from(context);
this.fullRequest = GlideApp.with(context).asBitmap();
}
private final Context mContext;
public List<CompactdArtist> getArtists() {
return artists;
}
void swapArtists (List<CompactdArtist> artists) {
this.artists.clear();
this.artists.addAll(artists);
notifyDataSetChanged();
}
private final List<CompactdArtist> artists;
@Override
public ArtistViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_artist_item, parent, false);
return new ArtistViewHolder(view);
}
@Override
public void onViewRecycled(ArtistViewHolder holder) {
super.onViewRecycled(holder);
Log.d(TAG, "onViewRecycled: ");
GlideApp.with(mContext).clear(holder.artistImageView);
holder.artistImageView.setImageDrawable(null);
}
@Override
public void onBindViewHolder(final ArtistViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: " + position);
final CompactdArtist current = artists.get(position);
// holder.setIsRecyclable(false);
holder.artistImageView.setImageDrawable(null);
try {
fullRequest.load(new MediaCover(current))
.fallback(ImageUtils.getFallback(mContext))
.into(new ImageViewTarget<Bitmap>(holder.artistImageView) {
@Override
protected void setResource(@Nullable Bitmap resource) {
if (resource == null) {
// holder.setIsRecyclable(true);
return;
}
holder.artistImageView.setImageBitmap(resource);
int color = Palette.from(resource).generate().getMutedColor(0xFFFFFF);
try {
current.fetch();
} catch (CouchbaseLiteException e) {
e.printStackTrace();
holder.artistNameText.setText(R.string.unknown_artist_name);
}
holder.artistBackground.setBackgroundColor(color);
holder.bindArtist(current);
holder.artistSub.setText(current.getAlbumCount() + " albums");
holder.artistNameText.setText(current.getName());
// holder.setIsRecyclable(true);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
super.onLoadCleared(placeholder);
// holder.setIsRecyclable(true);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public long getItemId(int position) {
return artists.get(position).getId().hashCode();
}
@Override
public int getItemCount() {
return this.artists.size();
}
@NonNull
@Override
public List getPreloadItems(int position) {
return this.artists.subList(position, position + 1);
}
@Nullable
@Override
public RequestBuilder<?> getPreloadRequestBuilder(Object item) {
MediaCover cover = (MediaCover) item;
return fullRequest.clone().thumbnail(0.2f).load(cover);
}
}
这是我的片段容器中的代码:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_artists, container, false);
mArtistRecyclerView = rootView.findViewById(R.id.artists_recyclerview);
LinearLayoutManager layoutManager = new GridLayoutManager(getContext(), 3);
mArtistRecyclerView.setLayoutManager(layoutManager);
mArtistsAdapter = new ArtistsAdapter(getActivity());
mArtistRecyclerView.setAdapter(mArtistsAdapter);
mArtistRecyclerView.setRecyclerListener(new RecyclerView.RecyclerListener() {
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
ArtistViewHolder artistViewHolder = (ArtistViewHolder) holder;
GlideApp.with(holder.itemView).clear(artistViewHolder.getArtistImage());
}
});
FixedPreloadSizeProvider<MediaCover> coverSizeProvider = new FixedPreloadSizeProvider<>(64, 64);
RecyclerViewPreloader<MediaCover> preloader = new RecyclerViewPreloader<MediaCover>(GlideApp.with(this), mArtistsAdapter, coverSizeProvider, 2);
return rootView;
}
作为奖励,我为MediaCover添加了访存程序:
/**
* Created by vinz243 on 13/12/2017.
*/
public class MediaCoverFetcher implements DataFetcher<InputStream> {
private final MediaCover mediaCover;
private boolean cancelled = false;
private InputStream stream;
public MediaCoverFetcher(MediaCover mediaCover) {
this.mediaCover = mediaCover;
}
@Override
public void loadData(Priority priority, DataCallback<? super InputStream> callback) {
CompactdArtwork artwork = mediaCover.getArtwork();
try {
stream = artwork.getImage(ArtworkSize.LARGE);
if (cancelled) {
callback.onLoadFailed(new RuntimeException("Cancelled"));
} else {
callback.onDataReady(stream);
}
} catch (NullPointerException e) {
callback.onLoadFailed(e);
}
}
@Override
public void cleanup() {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void cancel() {
cancelled = true;
}
@NonNull
@Override
public Class<InputStream> getDataClass() {
return InputStream.class;
}
@NonNull
@Override
public DataSource getDataSource() {
return DataSource.LOCAL;
}
}
我猜它来自回收部分,但我不知道如何解决该问题。 正如您可能在代码中看到的那样,我尝试了setIsRecyclable
但是会收到错误消息,指出无法匹配的调用,并且无法解决问题
您应该尝试更改几件事:
将您的CompactdArtist变量定义为最终变量
@Override public void onBindViewHolder(final ArtistViewHolder holder, int position) { Log.d(TAG, "onBindViewHolder: " + position); final CompactdArtist current = artists.get(position); // holder.setIsRecyclable(false); holder.bindArtist(artists.get(position)); holder.artistImageView.setImageDrawable(null); try { current.fetch(); fullRequest.load(new MediaCover(current)) .fallback(ImageUtils.getFallback(mContext)) .into(new ImageViewTarget<Bitmap>(holder.artistImageView) { @Override protected void setResource(@Nullable Bitmap resource) { if (resource == null) { // holder.setIsRecyclable(true); return; } holder.artistImageView.setImageBitmap(resource); int color = Palette.from(resource).generate().getMutedColor(0xFFFFFF); holder.artistBackground.setBackgroundColor(color); // holder.setIsRecyclable(true); holder.artistNameText.setText(current.getName()); holder.artistSub.setText(current.getAlbumCount() + " albums"); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { super.onLoadCleared(placeholder); // holder.setIsRecyclable(true); } }); } catch (CouchbaseLiteException e) { e.printStackTrace(); holder.artistNameText.setText(R.string.unknown_artist_name); } catch (IOException e) { e.printStackTrace(); } }
我认为加载图像的方式是异步的,因此在这种情况下,您的问题就在于您将变量设置为好像它们处于同步过程一样,这就是为什么将信息显示在错误的块上的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.