0

I´m using the first time ViewHolder with GridView and i´m new to android/java It´s working a lot of better then with ImageView.

But the biggest problem i have is that scrolling is laggy. I have two questions:

First one: What can I do to make performance better? Second one: Can I use and how can I use BitmapWorkerTask/AsyncTask with it?

What I tried was android:scrollingCache="false" as everybody is writting but it seems that performance is a little bit better for me with android:scrollingCache="true".

Code:

Layout

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
                  android:orientation="vertical"  
                  android:layout_width="fill_parent"  
                  android:layout_height="fill_parent"  
                  android:padding="10dp">  
    <ImageView android:id="@+id/ic_launcher"
    android:contentDescription="@string/desc"  
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:columnWidth="90dp"
    android:numColumns="4"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:fastScrollEnabled="true"
    android:persistentDrawingCache="scrolling"
    android:scrollingCache="true"
    android:animationCache="false"
    android:smoothScrollbar="true"
    /> 

    </LinearLayout> 

ImageAdapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;



public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private LayoutInflater mInflater; 


    // Keep all Images in array about 600
    public Integer[] mThumbIds = {

};
// Constructor
    public ImageAdapter(Context c) {   
        mInflater = LayoutInflater.from(c);  
           mContext = c;
    }

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

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

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



 // create a new ImageView for each item referenced by the     
    public View getView(int position, View convertView, ViewGroup parent) {     
     ViewHolder holder;
       if (convertView == null) {  // if it's not recycled,     
             convertView = mInflater.inflate(R.layout.categorycontent, null);  
           convertView.setLayoutParams(new GridView.LayoutParams(130, 130));  
          holder = new ViewHolder();  
             holder.icon = (ImageView )convertView.findViewById(R.id.ic_launcher);  
             convertView.setTag(holder);  
         } else {  
             holder = (ViewHolder) convertView.getTag();

         }  
holder.icon.setAdjustViewBounds(true);  
holder.icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);     
holder.icon.setImageResource(mThumbIds[position]);  
return convertView;     
    }     
    class ViewHolder {  
        ImageView icon;  
    }  }

I hope you dudes have some ideas for me :)

NewCodewithErrors

    }

    class ViewHolder {  
        ImageView icon;  
    } 

 // create a new ImageView for each item referenced by the     
    public View getView(int position, View convertView, ViewGroup parent) {     
     ViewHolder holder;
       if (convertView == null) {  // if it's not recycled,     
             convertView = mInflater.inflate(R.layout.categorycontent, null);  
           convertView.setLayoutParams(new GridView.LayoutParams(130, 130));  
          holder = new ViewHolder();  
             holder.icon = (ImageView )convertView.findViewById(R.id.ic_launcher);  
             convertView.setTag(holder);  
         } else {  
             holder = (ViewHolder) convertView.getTag();

         }  
holder.icon.setAdjustViewBounds(true);  
holder.icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);     
holder.icon.setImageResource(mThumbIds[position]);

//Here i have the errors:
//The constructor ImageAdapter.LoadImage() is undefine ImageAdapter.java
//The method execute(Integer...) in the type AsyncTask<Integer,Void,Bitmap> is not 
//applicable for the arguments (View) ImageAdapter.java

new LoadImage().execute(convertView);

return convertView;     
    }   


    private class LoadImage extends AsyncTask<Integer, Void, Bitmap> {

        private ImageView imv;

        public LoadImage(ImageView imv) {
            this.imv = imv;
        }

        @Override
        protected void onPostExecute(Bitmap result) {

            if (result != null && imv != null) {
                imv.setVisibility(View.VISIBLE);
                imv.setImageBitmap(result);
            } else {
                imv.setVisibility(View.GONE);
            }
        }

        @Override
        protected Bitmap doInBackground(Integer... params) {
            Bitmap bitmap = null;
            bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                    params[0]);
            return bitmap;
        }

    }}
  • You are loading images in the UI thats why your grid scroll is lagging..try to load it in Asynchtask.. – kalyan pvs Apr 07 '14 at 09:12
  • The code seems fine to me. I have used this multiple times, but I have never seen any scroll lag. Can you please explain the issue in a bit more detail. – drulabs Apr 07 '14 at 09:22
  • Could you guide me how to do that? or do you know a good tutorial or something else? thx @kalyanpvs –  Apr 07 '14 at 09:22
  • @skulldeath420 with small modification to the given kink,,you will get http://stackoverflow.com/questions/7729133/using-asynctask-to-load-images-in-listview – kalyan pvs Apr 07 '14 at 09:27
  • @KKD I´m making and learning on an app with 4 tabs(fragment) and fullscreenactivity were i can share images. On the first tab what is the code i posted i try that new and better solution and because that gridview tab has a little bit more then 600 pictures in it. The image loading is perfect but if i scroll fast because let´s say i want a picture from the end of the gridview it freeze and lags for a few seconds and that i don´t want. If i scroll really slow performance is not great but okay... –  Apr 07 '14 at 09:28
  • I don´t get it what modifications are needed :( If i put the line new LoadImage()... above the line return convertView and add at the end of my code that class LoadImage I have the error The constructor ImageAdapter.LoadImage() is undefined ImageAdapter.java @kalyanpvs –  Apr 07 '14 at 09:50
  • @skulldeath420 ok..wait i will post.. – kalyan pvs Apr 07 '14 at 09:52
  • @skulldeath420 change like that.. – kalyan pvs Apr 07 '14 at 09:58

1 Answers1

0

First take inner class in your Adapter like..

private class LoadImage extends AsyncTask<Integer, Void, Bitmap> {

    private ImageView imv;

    public LoadImage(ImageView imv) {
        this.imv = imv;
    }

    @Override
    protected void onPostExecute(Bitmap result) {

        if (result != null && imv != null) {
            imv.setVisibility(View.VISIBLE);
            imv.setImageBitmap(result);
        } else {
            imv.setVisibility(View.GONE);
        }
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        Bitmap bitmap = null;
        bitmap = BitmapFactory.decodeResource(mContext.getResources(),
                params[0]);
        return bitmap;
    }

}

And call it above the line return convertView

new LoadImage(holder.icon).execute(mThumbIds[position]);
kalyan pvs
  • 14,486
  • 4
  • 41
  • 59
  • I still have the same error with a new one. I added the new code in my question maybe you can see what i´m doing wrong. –  Apr 07 '14 at 10:08
  • //The constructor ImageAdapter.LoadImage() is undefine ImageAdapter.java //The method execute(Integer...) in the type AsyncTask is not //applicable for the arguments (View) ImageAdapter.java I added the code above. –  Apr 07 '14 at 10:10
  • @skulldeath420 have you called like this **new LoadImage(holder.icon).execute(mThumbIds[position]);** – kalyan pvs Apr 07 '14 at 10:10
  • yes it´s working i didn´t see that with holder.icon and so on :) But it´s not smoother it´s still the same and now the pictures are on the wrong place i mean you can see that it´s loading the new ones but that´s no problem for me. Do you have another idea for the performance? –  Apr 07 '14 at 10:15
  • @skulldeath420 Nope..thats the only solution..and move this two holder.icon.setAdjustViewBounds(true); holder.icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE); into inside of if(convertview==null) block – kalyan pvs Apr 07 '14 at 10:17
  • ok i solved the problem with the pictures on wrong place with: android:scrollingCache="false" but it´s still laggy –  Apr 07 '14 at 10:17
  • add this to your gridview in xml "android:fastScrollEnabled=true" – kalyan pvs Apr 07 '14 at 10:19
  • wrong information with cache false it takes longer to load.. and and moving the lines i think helped a little bit. Do you know if it´s possible to set a scroll speed limit? So let´s say i try to scroll over the display 4 times in a second but it only use one scroll with the finger? Or should i try to use a DiskLruCache? –  Apr 07 '14 at 10:25
  • i have fast scroll enabled. –  Apr 07 '14 at 10:26
  • @skulldeath420 You cant set the speed of scroll..that too dont expect that much scroll on image..its not text messages you are showing..its large Bitmap objects.. – kalyan pvs Apr 07 '14 at 10:28
  • i understand now what you mean. So do you think if i use DiskLruCache it could be better? –  Apr 07 '14 at 10:37