我想做一个允许我添加或删除一些照片的图片管理器。 如果可能的话,我不想使用外部库。现在我尝试为GridView做适配器并显示一些图片,用户使用相机拍摄,我有一些问题:
这是我的适配器:
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>
答案 0 :(得分:2)
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,否则你不能在那里做繁重的工作。对于处理getView等视图的方法尤其如此,它们对UI至关重要 你正在解码位图并从那里读取磁盘。
您应该看一下好的list / gridView库如何处理它。您必须实现ConvertView和ViewHandler设计模式才能与getView一起高效工作
此外,您需要实现自己的加载器来处理两个级别的文件:内存中的lruCache,如果它们不在缓存中,则从磁盘中获取它们。
一旦实现了这三件事,您的列表中应该有非常流畅的表现。官方Android开发网站上的列表视图和“有效显示位图”课程为这些主题提供了良好的起点。
编辑:关于LruCache。最近最少使用的缓存是一个缓存,当它变得太大时会自动删除它最少使用的条目(为了不占用太多内存非常方便)。 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
所以我不会在这里详细说明。