Java 如何在RecyclerView中显示多个图像?
我试图在android studio中开发一个画廊应用程序,我使用RecyclerView布局有效地加载屏幕上的图像,但每当我向下滚动时,在几个图像之后,应用程序就会崩溃。我得到的错误是java.lang.OutOfMemoryError,因此我认为我在类适配器上犯了错误,但我找不到任何错误(我遵循android文档中给出的步骤)。我试图显示每个图像的缩略图,而不是实际图像,但在向下滚动了几张图像后,应用程序崩溃了,我得到了该应用程序可能在其主线程上做了太多的工作错误 我将留下适配器类的代码。如果你需要更多的代码示例或更多信息,请告诉我 对不起,我不清楚,我的英语很差,我没有在这里提问的经验,而且这是我在android上的第一个应用 公共类MyAdapter扩展了RecyclerView.Adapter{Java 如何在RecyclerView中显示多个图像?,java,android,android-recyclerview,android-imageview,android-constraintlayout,Java,Android,Android Recyclerview,Android Imageview,Android Constraintlayout,我试图在android studio中开发一个画廊应用程序,我使用RecyclerView布局有效地加载屏幕上的图像,但每当我向下滚动时,在几个图像之后,应用程序就会崩溃。我得到的错误是java.lang.OutOfMemoryError,因此我认为我在类适配器上犯了错误,但我找不到任何错误(我遵循android文档中给出的步骤)。我试图显示每个图像的缩略图,而不是实际图像,但在向下滚动了几张图像后,应用程序崩溃了,我得到了该应用程序可能在其主线程上做了太多的工作错误 我将留下适配器类的代码。如
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;
public ViewHolder(@NonNull View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.IMAGEN);
}
}
private ArrayList<File> images = new ArrayList<>();
private Activity activity;
public MyAdapter(ArrayList<File> images, Activity activity){
this.images = images;
this.activity = activity;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
View v = activity.getLayoutInflater().inflate(R.layout.image_item, viewGroup, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//Bitmap myBitmap = BitmapFactory.decodeFile(images.get(position).getAbsolutePath());
//holder.image.setImageBitmap(myBitmap);
Picasso.get().load(images.get(position)).resize(300,300).centerCrop().into(holder.image);
}
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
super.onViewRecycled(holder);
holder.image.setImageBitmap(null);
}
@Override
public int getItemCount() {
return images.size();
}
public类ViewHolder扩展了RecyclerView.ViewHolder{
公众形象;
公共视图持有者(@NonNull View itemView){
超级(项目视图);
image=(ImageView)itemView.findViewById(R.id.IMAGEN);
}
}
私有ArrayList图像=新建ArrayList();
私人活动;
公共MyAdapter(ArrayList映像、活动){
这个。图像=图像;
这个。活动=活动;
}
@非空
@凌驾
public ViewHolder onCreateViewHolder(@NonNull ViewGroup ViewGroup,int viewType){
视图v=activity.GetLayoutFlater().充气(R.layout.image_项,视图组,false);
视窗支架vh=新视窗支架(v);
返回vh;
}
@凌驾
public void onBindViewHolder(@NonNull ViewHolder,int位置){
//位图myBitmap=BitmapFactory.decodeFile(images.get(position.getAbsolutePath());
//holder.image.setImageBitmap(myBitmap);
Picasso.get().load(images.get(position)).resize(300300.centerCrop())到(holder.image)中;
}
@凌驾
ViewRecycled上的公共无效(@NonNull ViewHolder){
super.onViewRecycled(支架);
holder.image.setImageBitmap(空);
}
@凌驾
public int getItemCount(){
返回图像。size();
}
}您可以使用Glide。
如果不需要,可以在onViewRecycled中清理图像
差不多
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
super.onViewRecycled(holder)
holder.image.setImageBitmap(null)
}
您可以使用Glide库在recycler视图中更高效地上载图像。另外,尝试先压缩位图,然后在图像视图中进行设置。 通过压缩映像,OutOfMemory异常将得到解决 取自某人的答案。现在不记得链接了吗
`public Bitmap compressInputImage(Uri inputImageData)
{
try
{
bitmapInputImage = MediaStore.Images.Media.getBitmap(context.getContentResolver(), inputImageData);
if (bitmapInputImage.getWidth() > 2048 && bitmapInputImage.getHeight() > 2048)
{
dpBitmap = Bitmap.createScaledBitmap(bitmapInputImage, 1024, 1280, true);
}
else if (bitmapInputImage.getWidth() > 2048 && bitmapInputImage.getHeight() < 2048)
{
dpBitmap = Bitmap.createScaledBitmap(bitmapInputImage, 1920, 1200, true);
}
else if (bitmapInputImage.getWidth() < 2048 && bitmapInputImage.getHeight() > 2048)
{
dpBitmap = Bitmap.createScaledBitmap(bitmapInputImage, 1024, 1280, true);
}
else if (bitmapInputImage.getWidth() < 2048 && bitmapInputImage.getHeight() < 2048)
{
dpBitmap = Bitmap.createScaledBitmap(bitmapInputImage, bitmapInputImage.getWidth(), bitmapInputImage.getHeight(), true);
}
} catch (Exception e)
{
dpBitmap = bitmapInputImage;
}
return dpBitmap;
}
公共位图压缩InputImage(Uri inputImageData)
{
尝试
{
bitmapInputImage=MediaStore.Images.Media.getBitmap(context.getContentResolver(),inputImageData);
if(bitmapInputImage.getWidth()>2048&&bitmapInputImage.getHeight()>2048)
{
dpBitmap=Bitmap.createScaledBitmap(bitmapInputImage,10241280,true);
}
else if(bitmapInputImage.getWidth()>2048&&bitmapInputImage.getHeight()<2048)
{
dpBitmap=Bitmap.createScaledBitmap(bitmapInputImage,1920,1200,true);
}
else if(bitmapInputImage.getWidth()<2048&&bitmapInputImage.getHeight()>2048)
{
dpBitmap=Bitmap.createScaledBitmap(bitmapInputImage,10241280,true);
}
else if(bitmapInputImage.getWidth()<2048&&bitmapInputImage.getHeight()<2048)
{
dpBitmap=Bitmap.createScaledBitmap(bitmapInputImage,bitmapInputImage.getWidth(),bitmapInputImage.getHeight(),true);
}
}捕获(例外e)
{
dpBitmap=bitmapInputImage;
}
返回dp位图;
}
更改此代码
Picasso.get().load(images.get(position)).resize(300,300).centerCrop().into(holder.image);
到
这将从外部存储器创建映像的实际URI
解决方案2
将此附加到您的图像中
file://
范例
Picasso.get().load("file://"+images.get(position)).resize(300,300).centerCrop().into(holder.image);
使用毕加索或glide在回收器视图中加载图像我找到了毕加索的教程,它展示了如何将毕加索的画廊应用程序制作为回收器视图,我将看看它是否有助于我找到问题的解决方案。谢谢我使用了毕加索,但甚至将图片大小调整为10x10像素。。。Picasso.get().load(images.get(position)).resize(10,10).centerCrop().into(holder.image);这还不够。我使用了ic_louncher_图标图像,它没有耗尽内存,我不知道我做错了什么…请在这里更新您的代码,以便我可以检查它并找到问题检查它,我已经更新了它,但它几乎是一样的…我试着重写onViewRecycled方法,但它没有工作,我再次得到了java.lang.OutOfMemoryError。。。我会重新研究一下我修好了!!!我将activity_main.xml的布局从ConstraintLayout更改为RelativeLayout,它成功了!我不知道为什么,所以我现在必须做一些布局的研究。谢谢你为帮助我所做的一切努力!
Picasso.get().load("file://"+images.get(position)).resize(300,300).centerCrop().into(holder.image);