如何在recyclerview中加载大量图像? [英] How to load large number of images in recyclerview?

查看:100
本文介绍了如何在recyclerview中加载大量图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动,允许用户选择约500张图像,然后转到下一个活动,这些图像将在RecyclerView中填充,我应该如何使它们全部起作用,以实现流畅的用户体验和更好的性能.

目前,我正在使用意图将图像作为位图进行传递.

我正在使用photopicker库进行照片选择,这里允许用户选择多个图像,所有选定图像的文件路径都存储在字符串Arraylist中,该字符串在活动的onActivityResult中返回,我将结果存储在下面名为mArray的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的下一个活动中,我正在此活动中接收发送的意图,并且意图中接收的数据是字符串的数组列表,其中包含用户在上一个活动中选择的图像的文件路径./p>

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 arraylist(这是位图图像的列表)传递给适配器.

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();
}

}

解决方案

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

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

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

String imageUriString = imageUri.getPath();

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

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

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

欢呼

I have an activity where user is allowed to select around 500 images and then moves to next activity where those images will populated in a RecyclerView, how should i make it all work, for smooth user experience and better performance.

Currently i'm passing the images as bitmaps using intents.

I'm using the photopicker library for photo selection, here user is allowed to select multiple images and the filepath of all the selected images gets stored in a string Arraylist, which gets returned in the onActivityResult of the activity, i'm storing the result in mUserSelectedPhotos named string arraylist below is some code for reference.

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);
        }
    }
}

on click of the next button the the user selected images string arraylist gets passed to the next activity through intent.

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);
        }
    });

In the next activity which contains the recyclerview, i'm receiving the sent intent within this activity and the received data in the intent is the arraylist of string which contains the filepaths of the images which user selected in the previous activity.

PhotoBookListViewActivity.java

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

i'm reading through the mReceivedImageList and converting the filepaths to bitmaps and storing it in the new bitmap arraylist.

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));
    }

passing the bitmapImages arraylist which is the list of bitmap images to the adapter.

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();
}

}

解决方案

I'd use Glide for this purpose, it loads images async, and loads the bitmap in the background. There absolutely no need for you to load a bunch of Bitmap-s at all. You just need a list of Uri-s or a list of their String representations

For each image in your list get a Uri String (path to file you already collect in String representation) and then just do something like this

If you stored Uri-s, first get the String value of the Uri for the image (if you already stored String representations od Uri-s skip the next line)

String imageUriString = imageUri.getPath();

Then use Glide to elegantly load the image to your container

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

Glide is a rather powerful tool, widely used, even recommended by Google, so there's no need to reinvent the wheel :)

Cheers

这篇关于如何在recyclerview中加载大量图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆