0

everybody, I get a problem that I use a listView to show hundreds of images from my local resources,and I set the image full of screen.There is a item with a imageView and a TextView in each list item.But when I slide to the next item ,it's not smoothly .I use the ImageFactory.options to adjust the scale of images.But the problem still exists.I guess maybe I should use asynctask loading and image cache to fix this problem. here is my code,hope you buddies point my problems.Thank you very much.

package com.jafir.project.adapter;


import java.util.List;
import java.util.Map;

import com.jafir.project.porunacabeza.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.RecyclerListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class PicListViewAdapter extends BaseAdapter  {
    private Context context;
    private Resources resources;
    private LayoutInflater inflater;
    private ViewHolder holder;
    private List<Map<String, Object>> list;
    public PicListViewAdapter(Context context,List<Map<String, Object>> list) {
        this.list = list;
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        resources = context.getResources();
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int arg0) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if(convertView == null) {
             convertView = inflater.inflate(R.layout.item_pic, null);
            holder =  new ViewHolder();
            holder.imageView = (ImageView) convertView.findViewById(R.id.img_pic);
            holder.textView = (TextView) convertView.findViewById(R.id.txt_pic);
            convertView.setTag(holder);

        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        int resID = (Integer) list.get(position).get("image");
        String text = (String) list.get(position).get("text");
        holder.imageView.setImageBitmap(decodeBitmap(resources, resID, holder.imageView.getWidth(),          holder.imageView.getHeight()));
        holder.textView.setText(text);
        notifyDataSetChanged();
        return convertView;
    }

    public Bitmap decodeBitmap(Resources res,int id,int width,int height){
        BitmapFactory.Options  options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res,id,options);
        options.inSampleSize = getInSampleSize(options,width,height);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res,id,options);
    }

    public int getInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
        final int width  = options.outWidth;
        final int height = options.outHeight;
        int inSampleSize = 1;
        if(height > reqHeight || width > reqWidth) {
            int radioWidth = Math.round((float)width/(float)reqWidth);
            int radioHeight = Math.round((float)height/(float)reqHeight);
            inSampleSize = radioHeight < radioWidth ?radioHeight:radioWidth;
        }
        return inSampleSize;
    }

      final static class ViewHolder{
            ImageView imageView;
            TextView textView;
        }
}

this is for activity:

 private void init() {
        listView = (ListView) getActivity().findViewById(R.id.lst_pic);
        list = new ArrayList<Map<String,Object>>();
        for(int i=0;i < texts.length;i++){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("image", R.drawable.img0+ i);
            map.put("text", texts[i]);
            list.add(map);
        }
        listView.setAdapter(new PicListViewAdapter(getActivity(), list));
    }

this is for item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:orientation="vertical"
 >

    <ImageView android:id="@+id/img_pic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />
    <TextView android:id="@+id/txt_pic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:gravity="center_horizontal"
        android:layout_gravity="center_horizontal"
        />


</LinearLayout>
Jafir
  • 93
  • 9

3 Answers3

0

There is a comprehensive guide on Android official site, please refer it at http://developer.android.com/training/displaying-bitmaps/index.html

The session contains the following topics:

Loading Large Bitmaps Efficiently This lesson walks you through decoding large bitmaps without exceeding the per application memory limit.

Processing Bitmaps Off the UI Thread Bitmap processing (resizing, downloading from a remote source, etc.) should never take place on the main UI thread. This lesson walks you through processing bitmaps in a background thread using AsyncTask and explains how to handle concurrency issues.

Caching Bitmaps This lesson walks you through using a memory and disk bitmap cache to improve the responsiveness and fluidity of your UI when loading multiple bitmaps.

Managing Bitmap Memory This lesson explains how to manage bitmap memory to maximize your app's performance.

Displaying Bitmaps in Your UI This lesson brings everything together, showing you how to load multiple bitmaps into components like ViewPager and GridView using a background thread and bitmap cache.

Robin
  • 10,052
  • 6
  • 31
  • 52
0

Your guess is correct. I've tested the implementation using the ViewRenderer (https://gist.github.com/tomgibara/1084229) from tomgibara maybe 2 years before, resulting in very smooth output. It's well

If I will try to give it a shot, I'll try to create a mechanism by myself. Some consideration for your reference:

  • Put the decoded bitmap into LRUCache so that you will not get a OutOfMemoryError. Seriously, this is probable when you are loading a lot of images.
  • Use AsyncTask/Loader/Raw Thread as you like. No much difference in essence.
Better Shao
  • 455
  • 4
  • 10
0

If I were you I would use that list adapter but within it use the picasso library to load the image. Picasso does not load images on the UI thread. That is why you are receiving this error. After adding the library, try making your getView() like so:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView == null) {
         convertView = inflater.inflate(R.layout.item_pic, null);
        holder =  new ViewHolder();
        holder.imageView = (ImageView) convertView.findViewById(R.id.img_pic);
        holder.textView = (TextView) convertView.findViewById(R.id.txt_pic);
        convertView.setTag(holder);

    }else {
        holder = (ViewHolder) convertView.getTag();
    }
    int resID = (Integer) list.get(position).get("image");
    String text = (String) list.get(position).get("text");
    //Picasso code
    Picasso.Builder builder = new Picasso.Builder(context);
    Picasso picasso = builder.build();
    picasso.load(resID).into(holder.imageView);
    //End Picasso code
    holder.textView.setText(text);
    notifyDataSetChanged();
    return convertView;
}
almyz125
  • 648
  • 1
  • 7
  • 18