Glide 用加载的图像部分覆盖屏幕
Glide overlays screen with loaded image parts
由于我在互联网上找不到任何相关内容,这将是我的第一个 SO 问题:
问题描述
我遇到了以下问题:
在我的应用程序中,我有一个 RecyclerView
和一个 GridLayoutManager
,它显示由 Glide 加载的图像。
缓慢滚动时一切正常。
快速上下滚动后(更进一步可以称之为"abuse of scrolling")一些图像部分或整个图像将随机覆盖我的屏幕,因此下面的内容不再可见。在屏幕边缘尤其如此。
出现上述错误的测试设备为一加一运行CM12.1.1(Android5.1.1)。我没有在其他设备上测试。
感谢任何关于为什么会发生这种情况或如何解决它的提示/帮助/解释。
代码
下面是带有内部 ViewHolder 的 Adapter 的代码 class:
public class PhotoListAdapter extends RecyclerView.Adapter<PhotoListAdapter.PhotoHolder>{
private ArrayList<PhotoDetail> mPhotos;
private String mAccessToken;
private int mUserId;
private int mPageCounter = 1;
private boolean mIsLoading = false;
private boolean mEndReached = false;
public PhotoListAdapter (String accessToken, int userId){
mPhotos = new ArrayList<>();
mAccessToken = accessToken;
mUserId = userId;
fetchPhotos();
}
@Override
public PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_photo_list_item, parent, false);
PhotoHolder photoHolder = new PhotoHolder(itemView);
return photoHolder;
}
@Override
public void onBindViewHolder(PhotoHolder holder, int position) {
holder.bind(mPhotos.get(position));
if (position == mPhotos.size() - 6) fetchPhotos();
}
@Override
public int getItemCount() {
return mPhotos.size();
}
public void fetchPhotos () {
if (mIsLoading || mEndReached) return;
else {
mIsLoading = true;
//Retrofit call which will return a JSON Object with the Photo Details, like the filename
// With this information i can build the URL of the image
ApiProvider.getInstance().getApi().getPhotos(mUserId, mAccessToken, "time", "all", mPageCounter, mUserId, 32).enqueue(new Callback<PhotoResponseWrapper>() {
@Override
public void onResponse(Call<PhotoResponseWrapper> call, Response<PhotoResponseWrapper> response) {
if (response.code() == HttpURLConnection.HTTP_OK){
int photoCount = response.body().getPhotoResponse().getPhotosCount();
if (photoCount != 32) mEndReached = true;
Collections.addAll(mPhotos, response.body().getPhotoResponse().getPhotos());
notifyItemRangeInserted(mPhotos.size() - photoCount,photoCount);
mPageCounter++;
}
mIsLoading = false;
}
@Override
public void onFailure(Call<PhotoResponseWrapper> call, Throwable t) {
mIsLoading = false;
}
});
}
}
class PhotoHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mPhotoView;
private PhotoDetail mPhotoDetail;
public PhotoHolder(View itemView) {
super(itemView);
mPhotoView = (ImageView) itemView.findViewById(R.id.img_photo);
mPhotoView.setOnClickListener(this);
}
public void bind (PhotoDetail photoDetail){
mPhotoDetail = photoDetail;
String photoUrl = Api.Endpoints.PHOTOS_SMALL + photoDetail.getUserId() + '/' + photoDetail.getFileName();
mPhotoView.setContentDescription(photoDetail.getDescription());
// First stop all pending image loads
Glide.clear(mPhotoView);
// Then load new url
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.into(mPhotoView);
}
@Override
public void onClick(View v) {
}
}
}
下面是单个项目的XML:
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/img_photo"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="@dimen/height_photo_item"
android:padding="@dimen/padding_photo_item"
android:scaleType="centerCrop"/>
下面是 RecyclerView 的 XML:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="@dimen/padding_photo_item"
android:paddingLeft="@dimen/padding_photo_item"
android:paddingTop="@dimen/padding_photo_item"
tools:context=".fragments.PhotoListFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
例子
错误的一些视觉示例是这些屏幕截图:
因为我找不到任何关于如何解决这个问题的信息,我尝试了主要的替代图像加载和缓存库 - Picasso。
使用这个库,上面提到的错误对我来说是不可重现的,所以我猜它真的是 Glide 特定的。
您必须使用占位符图像。
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.placeholder(R.drawable.image_placeholder) // Your placeholder image
.into(mPhotoView);
我遇到了同样的问题,设置占位符为我解决了这个问题。
由于我在互联网上找不到任何相关内容,这将是我的第一个 SO 问题:
问题描述
我遇到了以下问题:
在我的应用程序中,我有一个 RecyclerView
和一个 GridLayoutManager
,它显示由 Glide 加载的图像。
缓慢滚动时一切正常。
快速上下滚动后(更进一步可以称之为"abuse of scrolling")一些图像部分或整个图像将随机覆盖我的屏幕,因此下面的内容不再可见。在屏幕边缘尤其如此。
出现上述错误的测试设备为一加一运行CM12.1.1(Android5.1.1)。我没有在其他设备上测试。
感谢任何关于为什么会发生这种情况或如何解决它的提示/帮助/解释。
代码
下面是带有内部 ViewHolder 的 Adapter 的代码 class:
public class PhotoListAdapter extends RecyclerView.Adapter<PhotoListAdapter.PhotoHolder>{
private ArrayList<PhotoDetail> mPhotos;
private String mAccessToken;
private int mUserId;
private int mPageCounter = 1;
private boolean mIsLoading = false;
private boolean mEndReached = false;
public PhotoListAdapter (String accessToken, int userId){
mPhotos = new ArrayList<>();
mAccessToken = accessToken;
mUserId = userId;
fetchPhotos();
}
@Override
public PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_photo_list_item, parent, false);
PhotoHolder photoHolder = new PhotoHolder(itemView);
return photoHolder;
}
@Override
public void onBindViewHolder(PhotoHolder holder, int position) {
holder.bind(mPhotos.get(position));
if (position == mPhotos.size() - 6) fetchPhotos();
}
@Override
public int getItemCount() {
return mPhotos.size();
}
public void fetchPhotos () {
if (mIsLoading || mEndReached) return;
else {
mIsLoading = true;
//Retrofit call which will return a JSON Object with the Photo Details, like the filename
// With this information i can build the URL of the image
ApiProvider.getInstance().getApi().getPhotos(mUserId, mAccessToken, "time", "all", mPageCounter, mUserId, 32).enqueue(new Callback<PhotoResponseWrapper>() {
@Override
public void onResponse(Call<PhotoResponseWrapper> call, Response<PhotoResponseWrapper> response) {
if (response.code() == HttpURLConnection.HTTP_OK){
int photoCount = response.body().getPhotoResponse().getPhotosCount();
if (photoCount != 32) mEndReached = true;
Collections.addAll(mPhotos, response.body().getPhotoResponse().getPhotos());
notifyItemRangeInserted(mPhotos.size() - photoCount,photoCount);
mPageCounter++;
}
mIsLoading = false;
}
@Override
public void onFailure(Call<PhotoResponseWrapper> call, Throwable t) {
mIsLoading = false;
}
});
}
}
class PhotoHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mPhotoView;
private PhotoDetail mPhotoDetail;
public PhotoHolder(View itemView) {
super(itemView);
mPhotoView = (ImageView) itemView.findViewById(R.id.img_photo);
mPhotoView.setOnClickListener(this);
}
public void bind (PhotoDetail photoDetail){
mPhotoDetail = photoDetail;
String photoUrl = Api.Endpoints.PHOTOS_SMALL + photoDetail.getUserId() + '/' + photoDetail.getFileName();
mPhotoView.setContentDescription(photoDetail.getDescription());
// First stop all pending image loads
Glide.clear(mPhotoView);
// Then load new url
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.into(mPhotoView);
}
@Override
public void onClick(View v) {
}
}
}
下面是单个项目的XML:
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/img_photo"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="@dimen/height_photo_item"
android:padding="@dimen/padding_photo_item"
android:scaleType="centerCrop"/>
下面是 RecyclerView 的 XML:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="@dimen/padding_photo_item"
android:paddingLeft="@dimen/padding_photo_item"
android:paddingTop="@dimen/padding_photo_item"
tools:context=".fragments.PhotoListFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
例子
错误的一些视觉示例是这些屏幕截图:
因为我找不到任何关于如何解决这个问题的信息,我尝试了主要的替代图像加载和缓存库 - Picasso。
使用这个库,上面提到的错误对我来说是不可重现的,所以我猜它真的是 Glide 特定的。
您必须使用占位符图像。
Glide.with(mPhotoView.getContext())
.load(photoUrl)
.placeholder(R.drawable.image_placeholder) // Your placeholder image
.into(mPhotoView);
我遇到了同样的问题,设置占位符为我解决了这个问题。