Eric
Eric

Reputation: 1557

Where to Async in PagerAdatper

My fragment activity used this adapter to display all the result in a listview. The page will have a title tab and each tab will have the list result.
Now the list result I read from internal storage and each time I swipe to next page it will have slight lag or delay, so I am thinking implementing ASYNCTask inside this pageradapter so the experience will be better but I have no idea where to implement. Could you guys point me out??

public class ViewPagerAdapter extends PagerAdapter 
{        
public ViewPagerAdapter( Context context )
{
    //This is where i get my title
     for (HashMap<String, String> channels : allchannel){       
            String title = channels.get(KEY_TITLE);
            titles[acc] = title;
            acc++;
     }
       scrollPosition = new int[titles.length];

    for ( int i = 0; i < titles.length; i++ )
    {
        scrollPosition[i] = 0;
    }
}

@Override
public String getPageTitle( int position )
{           
    return titles[position];
}

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

@Override
public Object instantiateItem( View pager, final int position )
{
    String filename = null;
    ListView v = new ListView( context );
    final ArrayList<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();

    DatabaseHandler db = new DatabaseHandler(context);

    filename = openFile("PAGE1"); //OpenFile function is read file from internal storage
    switch(position){
    case 0:
        filename = openFile("PAGE1");
        break;
    case 1:
        filename = openFile("PAGE2");
    break;
    case 2:
        filename = openFile("PAGE3");
        break;
    }

       try{
        //Use json to read internal storage file(Page1/Page2) and display all the result on the list

        }
       }catch(Exception e){

       }

    ListAdapter listadapter=new ListAdapter(context, items);
    v.setAdapter( listadapter );
    ((ViewPager)pager ).addView( v, 0 );

    return v;
}

@Override
public void destroyItem( View pager, int position, Object view )
{
    ( (ViewPager) pager ).removeView( (ListView) view );
}

@Override
public boolean isViewFromObject( View view, Object object )
{
    return view.equals( object );
}

@Override
public void finishUpdate( View view )
{
}

@Override
public void restoreState( Parcelable p, ClassLoader c )
{
    if ( p instanceof ScrollState )
    {
        scrollPosition = ( (ScrollState) p ).getScrollPos();
    }
}

@Override
public Parcelable saveState()
{
    return new ScrollState( scrollPosition );
}

@Override
public void startUpdate( View view )
{
}

}

Upvotes: 0

Views: 729

Answers (2)

Shakti
Shakti

Reputation: 1581

I would suggest doing it like this

@Override
public Object instantiateItem( View pager, final int position )
{

//Some other work related to instantiation of item    

     AsyncTask<Uri, Void, Bitmap> mLoadTask = new AsyncTask<Uri, Void, Bitmap>() {              
     //async task for loading images in background

        @Override
        protected void onPostExecute(Bitmap result) {
            pageview[position].setImageBitmap(result);                                         
            //post in ui thread
            //this way you have a reference object for each item(using position)
            //and hence you can start several tasks at the same time             
        }

        @Override
        protected Bitmap doInBackground(Uri... params) {        
            Bitmap bitmap=getBitmap(params[0]);    
            //here getBitmap returns the bitmap using uri arguement
            return bitmap;
        }

    };
    mLoadTask.execute(Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + image_id));
}

This way each item has its own thread and you need not worry no matter how many items get loaded.

EDIT One more thing, you can return pageview[position] from this method right after the AsyncTask code, this way the View will appear blank(smooth scrolling achieved) until AsyncTask completes the background work. But it would still be able to set the Bitmap to the correct View because it has reference inside onPostExecute

Upvotes: 2

Pijetren
Pijetren

Reputation: 159

I'm doing it in constructor, and it's working fine. Example:

public MyAdapter(Context context) {
    this.context = context;
    try {
        whatIneed = new DoSomeAsyncStuff(this.context).execute().get();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }



}

Upvotes: 0

Related Questions