【问题标题】:ListView scroll lagging when images is shown?显示图像时ListView滚动滞后?
【发布时间】:2013-03-23 12:50:00
【问题描述】:

滚动时我的列表视图滞后。似乎延迟加载有效,但每次显示图像时都会发生延迟。

我正在使用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 异步加载图像 URL,这将是缓存图像的理想场所,你能看到如何使用链接中的 ImageLoader 来完成吗?

【问题讨论】:

    标签: android listview scroll lag


    【解决方案1】:

    是的,通过使用内存缓存解决滞后问题。您可以阅读来自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);
    }
    

    【讨论】:

      【解决方案2】:

      我通过创建和使用以下函数在后台缓存图像来解决它 在 ImageLoader.java 中

      public void cacheImage(String url){
          Bitmap bmp = getBitmap(url);
          memoryCache.put(url, bmp);
      }
      

      我创建了一个 ImageLoader 实例,对其进行了静态引用,然后调用

      AsyncClass.imageLoader.cacheImage(url);

      其中 AsyncClass 是我对 ImageLoader 进行静态引用并将其称为“imageLoader”的类。

      【讨论】:

        【解决方案3】:

        我建议您使用Android-Universal-Image-Loader 进行异步图像加载、缓存和显示。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-17
          相关资源
          最近更新 更多