使用加载的图像部件

时间:2016-03-07 22:27:29

标签: java android android-recyclerview recycler-adapter android-glide

由于我在互联网上找不到任何相关内容,这将是我的第一个问题:

问题说明

我遇到以下问题:
在我的应用中,我有一个RecyclerView,其中GridLayoutManager显示由Glide加载的图片。

当慢慢滚动时,一切都会正常工作。

快速上下滚动(可以说是一个可以称之为"滥用滚动")一些图像部分或整个图像将随机覆盖我的屏幕,以便下面的内容不再可见。在屏幕边缘尤其如此。

发生上述错误的测试设备是运行CM12.1.1(Android 5.1.1)的OnePlus One。我没有在其他设备上测试过。

对于为何发生这种情况或如何解决问题的任何提示/帮助/解释都表示赞赏。

CODE

以下是具有内部ViewHolder类的Adapter的代码:

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>

实施例

这些错误的一些可视化示例是这些屏幕截图:

Glide Bug Glide Bug

2 个答案:

答案 0 :(得分:2)

您必须使用占位符图片。

Glide.with(mPhotoView.getContext())
.load(photoUrl)
.placeholder(R.drawable.image_placeholder) // Your placeholder image
.into(mPhotoView);

我遇到了同样的问题,设置占位符为我取消了它。

答案 1 :(得分:0)

由于我无法找到有关如何解决此问题的任何信息,我尝试了主要的替代图像加载和放大器。缓存库 - Picasso
有了这个库,上面提到的bug对我来说是不可复制的,所以我猜它确实是Glide特有的。