我有一个ListView,每行都有一个ImageView。
我有一个customAdapter,可以为getView函数中的每一行加载图像。
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_row, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.listImage = (ImageView) row
.findViewById(R.id.list_image);
viewHolder.title = (TextView) row.findViewById(R.id.title);
viewHolder.description = (TextView) row
.findViewById(R.id.description);
row.setTag(viewHolder);
}
ItemDescription des = getItemDescriptionFromFile(items.get(position)
+ "/description.txt");
ViewHolder holder = (ViewHolder) row.getTag();
holder.title.setText(des.title);
holder.description.setText(des.description+(position)%5);
holder.listImage.setImageBitmap(getBitmapFromAsset(items.get(position));
return row;
}
private Bitmap getBitmapFromAsset(String strName) {
InputStream istr = null;
try {
istr = assetManager.open(strName);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(istr);
return bitmap;
}
但我注意到列表的滚动不够顺畅。
我搜索了我的问题,这个链接似乎是解决方案: http://developer.android.com/training/improving-layouts/smooth-scrolling.html
但是这段代码存在一些问题:
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
v.progress.setVisibility(View.GONE);
v.icon.setVisibility(View.VISIBLE);
v.icon.setImageBitmap(result);
}
}
}.execute(holder);
我无法访问内部类AsyncTask中的位置,因为position不是final。
有没有办法进入位置?
让列表顺利滚动的最佳方法是什么?
提前致谢。
答案 0 :(得分:0)
我建议您先将资产中的所有图像加载到内存中,然后再初始化适配器并从那里访问它,而不是在每次getView()
调用时执行磁盘I / O.这应该会带来显着的改善。
答案 1 :(得分:0)
您可以将具有静态对象的类用作缓存。这样,类对象将资源首次加载到内存中,在下一次调用中,使用缓存的访问时间将减少。要在下面的课程中实施,您只需拨打Bitmaps.getBitmapFromAsset(context,strName)
而不是自己的getBitmapFromAsset(strName)
。应该注意的是,在您离开应用程序之前,以这种方式用于资产的内存将不会被释放,因为您正在使用static
HastTable对象。
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class Bitmaps {
private static final Hashtable<String, Bitmap> cache = new Hashtable<String, Bitmap>();
public static Bitmap getBitmapFromAsset(Context c, String strName) {
synchronized (cache) {
if (!cache.containsKey(strName)) {
InputStream istr = null;
try {
istr = c.getAssets().open(strName);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(istr);
cache.put(strName, bitmap);
}
return cache.get(strName);
}
}
}