Android GridView crashes or is very slow on some devices (Samsung Galaxy S4, S3)

974 views Asked by At

I have a GridView in my app and it is really great on almost every device, but... I gave it to test for some friends and they said that my app crashes on GridView.. App crashes or they have to scroll in it really carefully. Some friends said that GridView is okay (also my - HTC Wildfire, Samsung Galaxy Mini), but my friends who have Samsung Galaxy S3, S4 say that it crash. My GridView:

public static List<Item> items = new ArrayList<Item>();

...

GridView gridView = (GridView) findViewById(R.id.gridview);
        items.clear();
//add all items to list

    gridView.setAdapter(new ImageAdapter(this, items));
            gridView.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View v,
                        int position, long id) {
                    Intent i = new Intent(getApplicationContext(), SecondActivity.class);
                    i.putExtra("id", position);
                    startActivity(i);

                }
            });

ImageAdapter:

public class ImageAdapter extends BaseAdapter {

    private List<Item> items = new ArrayList<Item>();
    private LayoutInflater inflater;

    public ImageAdapter(Context context, List<Item> items) {
        inflater = LayoutInflater.from(context);
        this.items = items;
    }

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

    @Override
    public Object getItem(int i) {
        return items.get(i);
    }

    @Override
    public long getItemId(int i) {
        return items.get(i).drawable;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View v = view;
        ImageView picture;
        TextView name;

        if (v == null) {
            v = inflater.inflate(R.layout.squareimageview, viewGroup, false);
            v.setTag(R.id.picture, v.findViewById(R.id.picture));
            v.setTag(R.id.text, v.findViewById(R.id.text));
        }

        picture = (ImageView) v.getTag(R.id.picture);
        name = (TextView) v.getTag(R.id.text);

        Item item = (Item) items.get(i);

        picture.setImageResource(item.getDrawable());
        name.setText(item.name);

        return v;

    }

}

My SquareImageView class, which size my GridView's elements to 2 columns and to look good on multiple screens:

public class SquareImageView extends ImageView {
    public SquareImageView(Context context) {
        super(context);
    }

    public SquareImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
    }

}
1

There are 1 answers

6
M-Wajeeh On BEST ANSWER

From the documentation of setImageResource(). (emphasize is mine)

This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that's a concern, consider using setImageDrawable(android.graphics.drawable.Drawable) or setImageBitmap(android.graphics.Bitmap) and BitmapFactory instead.

I strongly suggest you to use Picasso library for showing images. After adding library to your project call following function in getView():

Picasso.with(context).load(item.getDrawable()).into(picture);

and thats it.


public class ImageAdapter extends BaseAdapter {

    private List<Item> items = new ArrayList<Item>();
    private LayoutInflater inflater;

    private Context context; 

    public ImageAdapter(Context context, List<Item> items) {
        inflater = LayoutInflater.from(context);
        this.items = items;
        this.context = context;
    }
    .
    .
    .
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View v = view;
        ImageView picture;
        TextView name;

        if (v == null) {
            v = inflater.inflate(R.layout.squareimageview, viewGroup, false);
            v.setTag(R.id.picture, v.findViewById(R.id.picture));
            v.setTag(R.id.text, v.findViewById(R.id.text));
        }

        picture = (ImageView) v.getTag(R.id.picture);
        name = (TextView) v.getTag(R.id.text);

        Item item = (Item) items.get(i);

        Picasso.with(context).load(item.getDrawable()).into(picture);
        name.setText(item.name);

        return v; 
    }
}