Search code examples
androidandroid-viewpagerpicasso

Picasso image loader in ViewPager: Add fragments based on first come first serve


I am using Picasso as my image loader library. I have a ViewPager which shows some fragments with ImageViews. The images that are to be shown in the image view should be fetched from the network. My problem is that in the ViewPager I need to show only the images (Fragments) that are fetched successfully. Is it possible?


Solution

  • I found it myself. I am posting here because it may help some one who faces similar scenario.

    My ViewPagerAdapter is given below:

        import android.content.Context;
        import android.graphics.Bitmap;
        import android.graphics.drawable.Drawable;
        import android.support.v4.app.Fragment;
        import android.support.v4.app.FragmentManager;
        import android.support.v4.app.FragmentStatePagerAdapter;
    
        import com.squareup.picasso.Picasso;
        import com.squareup.picasso.Target;
    
        import java.util.ArrayList;
        import java.util.List;
    
        //ImageFragment is a normal fragment containing a ImageView
        import *****.ImageFragment;
    
    /**
     * Created by sanifss on 07/12/15.
     */
    public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        private final String[] urls;
        private final Context context;
        private List<String> urlList;
        private final boolean zoomEnabled;
        private List<MyTarget> targets;
    
        public ScreenSlidePagerAdapter(Context context, FragmentManager fm, String[] urls, boolean zoomEnabled) {
            super(fm);
            this.urls = urls;
            this.context = context;
            this.zoomEnabled = zoomEnabled;
            urlList = new ArrayList<>();
    
            targets = new ArrayList<>();
            fetchImages();//images are first loaded and then added to the adapter in FCFS.
        }
    
        private void fetchImages() {
            for (String url : urls) {
                MyTarget target = new MyTarget(url);
                targets.add(target);//needed otherwise target object will get garbage collected
                Picasso.with(context).load(url).into(target);
            }
        }
    
        @Override
        public Fragment getItem(int position) {
            //ImageFragment is a normal fragment containing a ImageView
            return ImageFragment.newInstance(urlList.get(position), zoomEnabled);
        }
    
        @Override
        public int getCount() {
            return urlList.size();
    
        }
    
        class MyTarget implements Target {
    
            private String url;
    
            public MyTarget(String url) {
                this.url = url;
            }
    
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                ScreenSlidePagerAdapter.this.urlList.add(url);
                ScreenSlidePagerAdapter.this.notifyDataSetChanged();
            }
    
            @Override
            public void onBitmapFailed(Drawable errorDrawable) {
            }
    
            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
            }
        }
    
    }