1

I have a question about GridView

public Class MyGribView extends BaseAdapter(){
...
...

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imgView;
    imgView=(ImageView)convertView;

    Bitmap bm = BitmapFactory.decodeFile(filepath[position]);
    Log.d("filePath",filepath[position]+"");

    imgView.setImageBitmap(bm);

    return imgView;
}
}

I got all image on external Android to array String filepath[] (link image) ok, but have a problem at line imgView.setImageBitmap(bm). How can I fix it?

J.K
  • 2,290
  • 1
  • 18
  • 29
쩐광억
  • 47
  • 8

2 Answers2

1

Use custom adapter with ViewHolder design pattern :

grid_item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/imgView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"/>

</LinearLayout>

MyGribView

class MyGribView extends BaseAdapter{

    private Context context;
    private String[] filepath;

    public MyGribView(Context context,String[] filepath){
        this.context=context;
        this.filepath=filepath;
    }

    @Override
    public int getCount() {
        return filepath.length;
    }

    @Override
    public Object getItem(int position) {
        return filepath[position];
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView==null){
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.grid_item,null);
            holder.imgView = (ImageView) convertView.findViewById(R.id.imgView);
            convertView.setTag(holder);
        }else{
            holder =(ViewHolder) convertView.getTag();
        }
        holder.imgView.setImageBitmap(decodeFile(filepath[position]));
        return convertView;
    }
    class ViewHolder{
        ImageView imgView;
    }
    public Bitmap decodeFile(String path) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, o);
            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;
            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >=REQUIRED_SIZE)
                scale *= 2;
            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeFile(path, o2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
}
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
  • error "Out of memory . . . byte allocation" . How can I fix it? thanks – 쩐광억 Dec 04 '14 at 13:46
  • Check : http://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object – Haresh Chhelana Dec 04 '14 at 13:52
  • 1
    I added BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 5; and change to BitMapFactory.decodeFile(filePath[positon],options)) – 쩐광억 Dec 04 '14 at 15:17
  • @NgọcTrầnQuang,please check updated ans where i can get bitamp using custon decode method which scaled bitamp to handle "Out of memory . . . byte allocation" exception. – Haresh Chhelana Dec 05 '14 at 04:17
  • do U know how to improve the speed load image ?@Haresh Chhelana – 쩐광억 Dec 06 '14 at 09:39
0

You never actually inflate a view or instantiate one. Also it is terrible for performance and memory usage to create a bitmap for every item in the list view, recycle your bitmaps.

The code below will probably fix your problem however it is also inefficient. If I were you I would look into the view holder pattern.

public Class MyGribView extends BaseAdapter(){
    ... 
    ... 

    public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imgView = new ImageView(context);
        imgView=(ImageView)convertView;

        Bitmap bm = BitmapFactory.decodeFile(filepath[position]);
        Log.d("filePath",filepath[position]+"");

        imgView.setImageBitmap(bm);

        return imgView;
    } 
} 
  • it's seem not work. :) . Can you show me how get image in external to GribView simple?I'm beginner . I searched Google but it's not clear . sorry i'm not good in English – 쩐광억 Dec 04 '14 at 03:45
  • You should be checking both if convertView is an instance of ImageView, and that it's not null. convertView will frequently be null, that's why you're always getting a null pointer. You should only create a new view if convertView does not meet those requirements. – Nathan Walters Dec 04 '14 at 03:52
  • @NathanWalters even that is a bad example my answer simply is the quickest way to get him working. Which is why i suggested he look into a viewholder pattern to reduce the views created and optimize the gridview – SemaphoreMetaphor Dec 04 '14 at 05:52
  • @bbaker The problem is that your answer *won't* get him working. Immediately after creating the ImageView, you reassign it to convertView, which is null. This doesn't solve anything. – Nathan Walters Dec 04 '14 at 12:57