gpt4 book ai didi

Android:带有图像的 GridView,如何设置动态大小并提高性能

转载 作者:行者123 更新时间:2023-11-29 21:43:29 25 4
gpt4 key购买 nike

我想做一个图像管理器,允许我添加或删除一些照片。如果可能的话,我不想使用外部库。现在我尝试为显示一些图片的 GridView 做适配器,这些图片是用户使用他的相机拍摄的,我有一些问题:

  1. 我想每行显示 3 张图片,我该怎么做? (现在我使用 imageView.setLayoutParams(layoutParams); 设置大小)
  2. 性能不是很好,我该如何改进它?因为理论上我应该放很多图片。

这是我的适配器:

public class CustomGalleryAdapter extends BaseAdapter {

private Context context;
private List<String> resources;

// Constructor
public CustomGalleryAdapter(Context context, List<String> resources){
super();

this.context = context;
this.resources = resources;
}

@Override
public int getCount() {
return resources.size();
}

@Override
public Object getItem(int position) {
return resources.get(position);
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

// Crea un ImageView
ImageView imageView = new ImageView(context);

// Carica un file dal path dato
File imgFile = new File(resources.get(position));

// Se l'immagine esiste
if(imgFile.exists()){

// Decodifica il Bitmap
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

// Setta il bitmap
imageView.setImageBitmap(myBitmap);
}

// Setta le proprietà dell'immagine
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
GridView.LayoutParams layoutParams = new GridView.LayoutParams(100, 150);
imageView.setLayoutParams(layoutParams);

// Ritorna l'immagine
return imageView;
}
}

这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="20dp"
android:numColumns="auto_fit"
android:columnWidth="90dp"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:gravity="center"
android:stretchMode="columnWidth" >
</GridView>

编辑:
我尝试修改,添加了 convertView 检查和 ViewHolder,但我不知道如何添加 LruCache 支持。非常感谢您的帮助!

获取 View 方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder;
if (convertView == null) {

Log.d("IMAGES","convertView = null");
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.cell_image, null);
holder.imageView = (ImageView) convertView.findViewById(R.id.cellImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

Log.d("IMAGES","decoding...");

// Decodifica il Bitmap
Bitmap myBitmap = BitmapFactory.decodeFile(resources.get(position));

// Setta il bitmap
holder.imageView.setImageBitmap(myBitmap);

return convertView;
}

ViewHolder:

class ViewHolder {
ImageView imageView;
}

细胞图像:

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/cellImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true" >

</ImageView>

最佳答案

 File imgFile = new  File(resources.get(position));

// Se l'immagine esiste
if(imgFile.exists()){

// Decodifica il Bitmap
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

// Setta il bitmap
imageView.setImageBitmap(myBitmap);

这是万恶之源。好吧,我有点夸张,但这很糟糕:每次调用 getView 时,你都在实例化一个新文件并解码它(它可以被调用很多次)。所以这不会带来好的表现。
为什么?
此代码在处理 UI 的主线程中运行。所以你不能在那里做繁重的工作,除非你想卡住 UI。对于处理 View 的方法(例如 getView)尤其如此,它们对 UI 至关重要。
你正在解码位图并从那里的磁盘读取。

您应该看看 list/gridView 库如何处理这个问题。您必须实现 ConvertView 和 ViewHandler 设计模式才能有效地使用 getView。
此外,您将需要实现自己的加载程序,在两个级别处理您的文件:内存中的 lruCache,如果它们不在缓存中,则从磁盘中获取它们。
一旦这 3 件事得到实现,您的列表中应该会有非常流畅的表现。官方 Android 开发网站上的 ListView 和“高效显示位图”类(class)为这些主题提供了良好的起点。


编辑:关于 LruCache。 The Least Recently Used cache 是一个缓存,当它变得太大时,它会自动删除其最少使用的条目(为了不占用太多内存,这非常方便)。 Android 已经提供了一个,它甚至是支持库 android.support.v4.util.LruCache 的一部分。
你想要做的不是直接读取文件并在 getView 中显示你的位图,而是调用一个 ImageLoader 来为你做这件事。
加载程序的实现由您决定。基本上你必须能够用图像的地址来调用它。首先它会检查它是否已经在内存中(从内存中读取比从磁盘中读取快得多)如果它在那里,直接显示它。
如果没有,您需要在另一个线程中工作。所有涉及繁重计算、磁盘或网络的事情都需要在主线程之外进行,以保持其性能。在另一个线程(使用 AsyncTask 或 ThreadPool)中,您将从磁盘读取文件,将其放入缓存并在主线程中显示。
官方文档已经有关于如何使用 Lrucache 的详细信息:
https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
以及如何在主线程之外处理位图:
https://developer.android.com/training/displaying-bitmaps/process-bitmap.html
所以我不会在这里详细说明。

关于Android:带有图像的 GridView,如何设置动态大小并提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16496587/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com