Search code examples
androidandroid-gridview

Lagged GridView


I'm showing a GridView of two columns with an adapter which displays information.

If the imatge is the same it scrolls really fast, but when the same quantity of images are displayed but they're diferent the scrolls lags a lot.

I tried to load with picaso and other libraries but I can't solve my problem.

(Sorry for my bad English)

My Adapter

package com.example.anonymous.mh4;


import android.content.Context;
import android.net.Uri;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;



import com.squareup.picasso.Picasso;

import java.io.File;
import java.lang.reflect.Field;

public class MonsterAdapter extends BaseAdapter {

    private final Context mContext;
    private final Monster[] monsters;

    public MonsterAdapter(Context context, Monster[] monsters) {
        this.mContext = context;
        this.monsters = monsters;
    }

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


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


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


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


        final Monster m = monsters[position];

        if (convertView == null) {
            final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            convertView = layoutInflater.inflate(R.layout.listviewitemmonster, null);
        }

        final ImageView imageView = (ImageView)convertView.findViewById(R.id.imglayout);
        final TextView nameTextView = (TextView)convertView.findViewById(R.id.namelayout);


        //getDrawableId(m.getIcon());



        //imageView.setImageResource(R.drawable.a1);


        // Picasso.with(mContext).load(R.drawable.a1).into(imageView);



        nameTextView.setText(m.getName());
        int id = mContext.getResources().getIdentifier(m.getIcon(), "drawable", mContext.getPackageName());
        imageView.setImageResource(id);

        //Glide.with(mContext).load("R.drawable."+m.getIcon()).into(imageView);

        /**Picasso.with(mContext).load(id)
                .error(R.drawable.unknow)
                .into(imageView);
        **/
        return convertView;

    }
}

EDITED

package com.example.anonymous.mh4;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;


import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.lang.reflect.Field;

public class MonsterAdapter extends BaseAdapter {





    private final Context mContext;


    private final Monster[] monsters;

    public MonsterAdapter(Context context, Monster[] monsters) {
        this.mContext = context;
        this.monsters = monsters;
    }



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


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


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


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


        final Monster m = monsters[position];

        if (convertView == null) {
            final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            convertView = layoutInflater.inflate(R.layout.listviewitemmonster, null);
        }

        final ImageView imageView = (ImageView)convertView.findViewById(R.id.imglayout);
        final TextView nameTextView = (TextView)convertView.findViewById(R.id.namelayout);


        //getDrawableId(m.getIcon());

        int id = mContext.getResources().getIdentifier(m.getIcon(), "drawable", mContext.getPackageName());
        Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), id);

        //imageView.setImageResource(R.drawable.a1);


        // Picasso.with(mContext).load(R.drawable.a1).into(imageView);

        //Picasso.with(mContext).load("file:///android_asset/DvpvklR.png").into(imageView2);

        nameTextView.setText(m.getName());
        imageView.setImageBitmap(bm);

        //imageView.setImageResource(id);

        //Glide.with(mContext).load("R.drawable."+m.getIcon()).into(imageView);

        /**Picasso.with(mContext).load(id)
                .error(R.drawable.unknow)
                .into(imageView);
        **/
        return convertView;

    }
}

IT WORKS, BUT LAGGED TOO


Solution

  • The cause for your problem is that setImageResource() is an expensive synchronous operation that involves decoding of the images.

    Except from reducing the image quality your other option is to somehow cache the images before you start the list (this can only be done if your list is not very long and preferably in a background thread).

    In short, you go over your list and build an array of resources:

    Bitmap bm = BitmapFactory.decodeResource(getResources(), getIcon());
    saveToMap(R.drawable.image, bm);
    

    When you need to show an image you'll do something like:

    iconView.setImageBitmap(getFromMap(getIcon()));
    

    You can use a HashMap to save/get the bitmaps or use some other data structure (an array if your list is constant). You probably also have to handle bitmap/recycling and memory management to make this solution work well.