滚动时我的列表视图滞后。似乎lazyload工作,但每次显示图像时都会出现延迟。
我正在使用此处http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/找到的imageLoader,这是我的适配器:
public class EventAdapter extends ArrayAdapter<Event>{
public ListImageLoader imageLoader;
public DisplayImageOptions imgDispOpts;
private ArrayList<Event> objects;
public EventAdapter(Context context, int textViewResourceId, ArrayList<Event> objects,ListImageLoader imageLoader) {
super(context, textViewResourceId, objects);
this.objects = objects;
this.imageLoader = imageLoader;
}
/*
* we are overriding the getView method here - this is what defines how each
* list item will look.
*/
@SuppressLint("DefaultLocale")
@Override
public View getView(int position, View convertView, ViewGroup parent){
Event event = objects.get(position);
// assign the view we are converting to a local variable
View v = convertView;
ViewHolder holder;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_row, null);
System.out.println("new Viewholder");
holder = new ViewHolder();
holder.listTimeString = (TextView) v.findViewById(R.id.listTimeString);
holder.date =(TextView) v.findViewById(R.id.Date);
holder.title = (TextView) v.findViewById(R.id.title);
holder.shortInfo = (TextView) v.findViewById(R.id.shortinfo);
holder.ageIcon = (ImageView) v.findViewById(R.id.listAgeIcon);
holder.thumb = (ImageView) v.findViewById(R.id.wideListImage);
holder.header = (RelativeLayout) v.findViewById(R.id.headerLayout);
holder.rowLayout = (RelativeLayout) v.findViewById(R.id.rowlayout);
holder.listVenueIcon = (ImageView) v.findViewById(R.id.listVenueIcon);
holder.eventRowLayout = (RelativeLayout) v.findViewById(R.id.eventrowlayout);
v.setTag(holder);
}
else{
holder = (ViewHolder) v.getTag();
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list. (The ArrayAdapter
* iterates through the list we sent it)
*
* Therefore, i refers to the current Item object.
*/
if (event != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
//SET FONTS
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/myriad.otf");
holder.title.setTypeface(tf);
holder.shortInfo.setTypeface(tf);
Typeface tf2 = Typeface.createFromAsset(getContext().getAssets(),"fonts/agencyr.ttf");
holder.date.setTypeface(tf2);
// check to see if each individual textview is null
// if not, assign some text!
if(event.isBig()){
//holder.rowLayout.getLayoutParams().height=230;
holder.shortInfo.setHeight(80);
holder.shortInfo.setMaxLines(5);
holder.shortInfo.setText(event.getInfo());
}
else{
//holder.rowLayout.getLayoutParams().height=125;
//holder.listVenueIcon.setImageResource(R.drawable.ikon_bar);
holder.shortInfo.setHeight(16);
holder.shortInfo.setMaxLines(1);
holder.shortInfo.setText(event.getInfo());
}
if(event.isClub()){
holder.listVenueIcon.setImageResource(R.drawable.ikon_klubb);
}
else{
holder.listVenueIcon.setImageResource(R.drawable.ikon_bar);
}
if (event.isNewDay()){
holder.date.setText(event.getDay().toUpperCase());
holder.header.setVisibility(View.VISIBLE);
} else{
holder.header.setVisibility(View.GONE);
}
if (holder.title != null){
holder.title.setText(event.getHost().toUpperCase());
}
if(holder.ageIcon!= null){
switch(Integer.parseInt(event.getAge())){
case(19):
holder.ageIcon.setImageResource(R.drawable.event_info_19);
break;
...
more cases
...
case(30):
holder.ageIcon.setImageResource(R.drawable.event_info_30);
break;
default:
holder.ageIcon.setImageResource(R.drawable.event_info_18);
break;
}
}
if(holder.thumb != null){
imageLoader.DisplayImage(event.getThumbURL(), holder.thumb);
}
if(holder.listTimeString != null){
String tempTimeString = event.getStartTime() + " - " + event.getEndTime();
holder.listTimeString.setText(tempTimeString);
}
}
// the view must be returned to our activity
return v;
}
static class ViewHolder{
RelativeLayout eventRowLayout;
TextView listTimeString;
TextView date;
TextView title;
TextView shortInfo;
ImageView ageIcon;
ImageView thumb;
RelativeLayout header;
RelativeLayout rowLayout;
ImageView listVenueIcon;
}
}
有什么想法吗?
编辑:我在onCreate上异步加载imageURL,这将是一个缓存图像的理想场所,你能看到如何使用链接中的ImageLoader完成这项工作吗?
答案 0 :(得分:2)
是的,通过使用内存缓存来解决滞后问题。您可以从here阅读原始帖子。
我实现了我的EntryArrayAdapter,它使用内存缓存来防止滚动列表视图时出现缓慢和滞后。
public class EntryArrayAdapter extends ArrayAdapter<JSONObject> {
private final Context context;
private final ArrayList<JSONObject> values;
private final LruCache<String, Bitmap> cache;
static class ViewHolder {
public TextView title;
public TextView city;
public TextView outlet;
public TextView service;
public ImageView photo;
}
public EntryArrayAdapter(Context context, ArrayList<JSONObject> values) {
super(context, R.layout.layout_list_item);
this.context = context;
this.values = values;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
cache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getRowBytes() / 1024;
}
};
}
/* (non-Javadoc)
* @see android.widget.ArrayAdapter#getCount()
*/
@Override
public int getCount() {
return values != null ? values.size() : 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder holder;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.layout_list_item, parent, false);
// set references
holder = new ViewHolder();
holder.title = (TextView) rowView.findViewById(R.id.titleText);
holder.city = (TextView) rowView.findViewById(R.id.cityText);
holder.outlet = (TextView) rowView.findViewById(R.id.outletText);
holder.service = (TextView) rowView.findViewById(R.id.visaMasterText);
holder.photo = (ImageView) rowView.findViewById(R.id.itemImage);
rowView.setTag(holder);
}
else {
holder = (ViewHolder) rowView.getTag();
}
try {
JSONObject obj = values.get(position);
Bitmap bmp = getBitmapFromMemCache(obj.getString("id"));
if (bmp == null) {
bmp = BitmapHelper.decodeSampledBitmapFromResource(obj.getString("photo"), 96, 96);
addBitmapToMemoryCache(obj.getString("id"), bmp);
}
holder.title.setText(obj.getString("title"));
holder.city.setText(obj.getString("city"));
holder.outlet.setText(obj.getString("outlet"));
holder.service.setText(obj.getString("service"));
holder.photo.setImageBitmap(bmp);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rowView;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
cache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return cache.get(key);
}
答案 1 :(得分:1)
我通过创建和使用以下函数在后台缓存图像来解决它 在ImageLoader.java中
public void cacheImage(String url){
Bitmap bmp = getBitmap(url);
memoryCache.put(url, bmp);
}
我创建了一个ImageLoader实例,对其进行了静态引用,然后调用
AsyncClass.imageLoader.cacheImage(URL);
其中AsyncClass是我对ImageLoader进行静态引用并将其称为“imageLoader”的类。
答案 2 :(得分:0)
我建议您使用Android-Universal-Image-Loader进行异步图像加载,缓存和显示。