Android: GridView,图像,如何设置动态大小和提高性能

标签: Android
发布时间: 2013/11/23 18:45:06
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我想要的图像管理器,让我可以添加或删除一些照片。我不想使用外部库,如果可能的话。现在我试着做和适配器为 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 支持。帮助非常感谢 !

getView 方法:

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

cell_image:

<?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>

解决方法 1:

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

这是所有罪恶的根源。好的我夸大,但这是不好: 你是一个新的文件 instanciating 和解码它每次调用 getView (和它可以调用很多)。所以这不能导致表现良好。
为什么呢?
这段代码运行在主线程中,处理 UI 的那个。所以你不能做重除非你想要冻结 UI 在那里工作。特别是处理视图如 getView,他们是 UI 的关键的方法。
你是解码的位图,从那里的磁盘中读取。

你应该看看如何好列表/gridView 库处理此。您必须实施的 ConvertView 和 ViewHandler 的设计模式,与 getView 有效地工作。
此外,您将需要实现您自己加载程序处理您的文件在两个层面: 在你的记忆,如果它们不在缓存中,从磁盘读取的 lruCache。
一旦将实施这些 3 的事情,您应该在您的列表中非常顺利演出。Listview 和 '有效地显示位图' 的教训,在官方的 Android 开发网站上对这些议题提供很好的起点。


编辑: 关于 LruCache。最近最少使用的缓存是缓存,当它变得太大时,将自动删除其最少使用的条目 (这是极大的方便,不需要太多的内存)。Android 系统已经提供了一个、 甚至是一部分的支持库 android.support.v4.util.LruCache
你想做的是而不是直接读取的文件和在 getView 中显示您的位图,调用将会为你做这 ImageLoader。
加载程序的执行是由你。基本上必须能够调用它的图像的地址。首先,它将检查是否它已经在内存 (它是极大地更快地从内存比从磁盘中读取) 如果它在那里,直接显示它。
如果没有,您需要在另一个线程中工作。一切都涉及重计算、 磁盘或网络的需求,在主线程外须保留它的性能。在另一个线程 (无论与 AsyncTask 或线程池) 你将会从磁盘读取该文件把它放在缓存中和回在主线程中显示它。
官方的 doc 上如何处理 Lrucache 已有详细信息:
https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
和如何处理位图关闭主线程:
https://developer.android.com/training/displaying-bitmaps/process-bitmap.html
所以不会详述这项在这里。

官方微信
官方QQ群
31647020