【问题标题】:How to load large number of images in recyclerview?如何在recyclerview中加载大量图像?
【发布时间】:2019-05-10 21:47:47
【问题描述】:

我有一个活动,允许用户选择大约 500 张图像,然后移动到下一个活动,这些图像将填充到 RecyclerView 中,我应该如何使其全部工作,以获得流畅的用户体验和更好的性能。

目前我正在使用意图将图像作为位图传递。

我正在使用 photopicker 库进行照片选择,这里允许用户选择多个图像,并且所有选定图像的文件路径都存储在字符串 Arraylist 中,该字符串在活动的 onActivityResult 中返回,我是将结果存储在名为字符串数组列表的 mUserSelectedPhotos 下面是一些代码供参考。

PhotoPickingActivity.java

mPickImagesButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            PhotoPicker.builder()
                    .setPhotoCount(200)
                    .setShowCamera(true)
                    .setShowGif(true)
                    .setPreviewEnabled(true)
                    .start(ChoosePhotoBookImagesActivity.this, PhotoPicker.REQUEST_CODE);
        }
    });


   @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK && requestCode == PhotoPicker.REQUEST_CODE) {
        if (data != null) {
            mUserSelectedPhotos =
                    data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
        }
    }
}

单击下一个按钮时,用户选择的图像字符串数组列表通过意图传递给下一个活动。

PhotoPickingActivity.java

 mNextButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(PhotoPickingActivity.this, PhotoBookListViewActivity.class);
            intent.putStringArrayListExtra("USER_SELECTED_IMAGES", mUserSelectedPhotos);
            startActivity(intent);
        }
    });

在包含 recyclerview 的下一个活动中,我在此活动中接收发送的意图,并且在意图中接收到的数据是字符串的数组列表,其中包含用户在上一个活动中选择的图像的文件路径。

PhotoBookListViewActivity.java

Intent intent = getIntent();
mReceivedImageList = intent.getStringArrayListExtra("USER_SELECTED_IMAGES");

我正在阅读 mReceivedImageList 并将文件路径转换为位图并将其存储在新的位图数组列表中。

PhotoBookListViewActivity.java

 final ArrayList<PhotoBookViewModel> bitmapImages = new ArrayList<PhotoBookViewModel>();

    for (int i = 0; i < mImageList.size(); i++) {
        mPhotoUrl = mImageList.get(i).toString();
        Bitmap myBitmap = BitmapFactory.decodeFile(mPhotoUrl);
        bitmapImages.add(new PhotoBookViewModel(myBitmap));
    }

将作为位图图像列表的 bitmapImages 数组列表传递给适配器。

PhotoBookListViewActivity.java

mPhotoBookViewAdapter = new PhotoBookViewAdapter(PhotoBookListViewActivity.this, bitmapImages);

mPhotoBookViewRecyclerView.setAdapter(mPhotoBookViewAdapter);

mPhotoBookViewRecyclerView.setLayoutManager(new LinearLayoutManager(PhotoBookListViewActivity.this, LinearLayoutManager.VERTICAL, false));

PhotoBookViewModel.java

import android.graphics.Bitmap;

public class PhotoBookViewModel {

private Bitmap mImageRes;

public PhotoBookViewModel(Bitmap imageRes) {
    this.mImageRes = imageRes;
}

public Bitmap getImageRes() {
    return mImageRes;
}
}

PhotoBookViewAdapter.java

public class PhotoBookViewAdapter extends RecyclerView.Adapter<PhotoBookViewAdapter.PhotoViewHolder> {

private ArrayList<PhotoBookViewModel> mData;
private LayoutInflater mLayoutInflater;
private View mImageItemView;
private ArrayList<String> mSelectedPhotos;
private Bitmap mBitmap;
private Context mContext;

public class PhotoViewHolder extends RecyclerView.ViewHolder {

    private ImageView mImageView;

    public PhotoViewHolder(@NonNull View itemView) {
        super(itemView);
        mImageView = itemView.findViewById(R.id.imageview);
    }

    public void setData(PhotoBookViewModel currentObj) {
        this.mImageView.setImageBitmap(currentObj.getImageRes());
    }
}

public PhotoBookViewAdapter(Context context, ArrayList<String> selectedPhotos) {
    this.mContext = context;
    this.mSelectedPhotos = selectedPhotos;
    mBitmap = BitmapFactory.decodeFile (mSelectedPhotos.get(0).toString());
}

public PhotoBookViewAdapter(Context context, ArrayList<PhotoBookViewModel> mData) {
    this.mData = mData;
    mLayoutInflater = LayoutInflater.from(context);
}

@NonNull
@Override
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    mImageItemView = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.photo_book_view_image_item, viewGroup, false);
    PhotoViewHolder photoViewHolder = new PhotoViewHolder(mImageItemView);
    mContext = viewGroup.getContext();
    return photoViewHolder;
}

@Override
public void onBindViewHolder(@NonNull PhotoViewHolder photoViewHolder, int position) {
    PhotoBookViewModel currentObj = mData.get(position);
    photoViewHolder.setData(currentObj);;
}

@Override
public int getItemCount() {
    return mData.size();
}

}

【问题讨论】:

  • 在此处发布您的代码
  • 贴一些代码让击球手不理解。
  • 有意传递 uri
  • 欢迎来到stackoverflow!请查看以下链接,以便我们获得更多帮助:stackoverflow.com/help/how-to-ask
  • 您可以将图片路径存储在sqlite中,然后在另一个活动中查询它们。

标签: android image android-recyclerview


【解决方案1】:

我会为此使用Glide,它异步加载图像,并在后台加载位图。您完全不需要加载一堆 Bitmap-s。您只需要一个 Uri-s 列表或其字符串表示形式的列表

为列表中的每个图像获取一个 Uri 字符串(您已经以字符串表示形式收集的文件的路径),然后执行类似的操作

如果你存储了 Uri-s,首先获取图像的 Uri 的 String 值(如果你已经存储了 String 表示 od Uri-s 跳过下一行)

String imageUriString = imageUri.getPath();

然后使用 Glide 优雅地将图像加载到您的容器中

Glide.with(myContext)
    .load(new File(imageUriString))
    .into(R.id.image_container);

Glide 是一个相当强大的工具,被广泛使用,甚至被 Google 推荐,因此无需重新发明轮子 :)

干杯

【讨论】:

  • 使用 Glide 是最好的方法,我不知道为什么我之前没有想到这一点,谢谢@Slobodan Antonijević。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
相关资源
最近更新 更多