Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is the instantiateItem(), inside my View Pager Adapter working?

Tags:

android

What am I trying to achieve?

I have url links to 5 images. I want them to be displayed on my HomeScreen in the form of a slideshow.

Do I know how to do that?

To my best knowledge, yes. I am able to get the 5 images displayed in the form of an automatic slideshow inside the HomeScreen

What is the problem then?

The 1st image that is being loaded is actually from the url at the 2nd index position, i.e the 3rd url.

An Overview of what i am doing in text

I have stored the urls of the images in a string array. I am passing the context of my homescreen and the url array to my View Pager Adapter. I am using Glide to display the images, inside the instantiateItem() method of the Adapter

The Code

HomeScreenTopPagerAdapter.java

public class HomeScreenTopPagerAdapter extends PagerAdapter {

    private String[] urls;
    private LayoutInflater layoutInflater;
    private Context context;
    private int custom_position = 0;

    public  HomeScreenTopPagerAdapter(Context context, String[] urls){
        this.context = context;
        this.urls = urls;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;           //to make automatic image slider come back to first image smoothly, by hypothetically making the image views infinite
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
        return view==o;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull final ViewGroup container, int position) {

        if(custom_position>urls.length-1)        //done for a smooth transition when there is a slideshow between last image and the first one
            custom_position=0;

        View view = layoutInflater.inflate(R.layout.home_screen_topimageslider,container,false);
        ImageView imageView = view.findViewById(R.id.topImageSliderImageView);
        final ProgressBar progressBar = ((HomeScreen)context).findViewById(R.id.progresBarHomeScreenTop);
        progressBar.setVisibility(View.VISIBLE);

        GlideApp.with(context)
                .load(urls[custom_position])
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        progressBar.setVisibility(View.GONE);
                        Toast.makeText(context,"Please Check Your Internet Connection",Toast.LENGTH_LONG).show();
                        Log.i("In Glide Loading Failed",Integer.toString(custom_position));
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        progressBar.setVisibility(View.GONE);
                        Log.i("In Glide Resource Ready",Integer.toString(custom_position));
                        //((HomeScreen)context).prepareDots(custom_position);
                        return false;
                    }
                })
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(imageView);

        container.addView(view);
        Log.i("Outside Glide ",Integer.toString(custom_position));
        custom_position++;
        return view;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        View view = (View)object;
        container.removeView(view);
    }
}

The Logcat

2019-06-19 09:50:46.728 29185-29185/? I/Outside Glide: 0
2019-06-19 09:50:46.731 29185-29185/? I/Outside Glide: 1
2019-06-19 09:50:46.741 29185-29210/? I/Adreno: QUALCOMM build                   : 4c638fb, I557c585805
    Build Date                       : 10/06/18
    OpenGL ES Shader Compiler Version: EV031.25.03.01
    Local Branch                     : 
    Remote Branch                    : 
    Remote Branch                    : 
    Reconstruct Branch               : 
2019-06-19 09:50:46.742 29185-29210/? I/Adreno: Build Config                     : S L 6.0.7 AArch64
2019-06-19 09:50:46.745 29185-29210/? I/Adreno: PFP: 0x005ff112, ME: 0x005ff066
2019-06-19 09:50:46.748 29185-29210/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-06-19 09:50:46.748 29185-29210/? I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-06-19 09:50:46.749 29185-29210/? I/OpenGLRenderer: Initialized EGL, version 1.4
2019-06-19 09:50:46.770 29185-29216/? I/DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
2019-06-19 09:50:48.034 29185-29185/com.example.gofresh I/In Glide Resource Ready: 2
2019-06-19 09:50:48.204 29185-29185/com.example.gofresh I/In Glide Resource Ready: 2
2019-06-19 09:50:52.324 29185-29185/? I/Outside Glide: 2
2019-06-19 09:50:52.953 29185-29185/? I/In Glide Resource Ready: 3
2019-06-19 09:50:55.066 29185-29185/? I/Outside Glide: 3
2019-06-19 09:50:55.722 29185-29185/? I/In Glide Resource Ready: 4
2019-06-19 09:50:57.273 29185-29185/? I/Outside Glide: 4
2019-06-19 09:50:58.611 29185-29185/? I/In Glide Resource Ready: 5
2019-06-19 09:50:59.327 29185-29185/? I/Outside Glide: 0
2019-06-19 09:50:59.342 29185-29185/? I/In Glide Resource Ready: 1
2019-06-19 09:51:03.633 29185-29185/? I/Outside Glide: 1
2019-06-19 09:51:03.655 29185-29185/? I/In Glide Resource Ready: 2

As you can see from the Logcat, it goes inside the Glide Method only when the Outside Glide: 0 and Outside Glide: 1 are happening. I am not being able to understand how this instantiateItem() method is actually working.

Also, I assumed that whenever In Glide Resource Ready will displayed in the Log, just after that the Outside Glide will be shown(i.e for the image at a particular index position, both will be displayed simultaneously), however Outside Glide is being shown ONLY AFTER the slideshow goes to the next image. In short, whenever the slideshow goes to an image, the Outside Glide with the index position of the previous image is being displayed and then the In Glide Resource Ready with the index of the current image is being displayed.

Homescreen.java

    private ViewPager viewPager;
    private HomeScreenTopPagerAdapter adapter;
    private String[] urls = {"https://picsum.photos/420/200/?temp=1",               ///?temp=randomNo/String doesn't change the URL. Added so that each image is random
                     "https://picsum.photos/420/200/?temp=2",
                     "https://picsum.photos/420/200/?temp=3",
                     "https://picsum.photos/420/200/?temp=4",
                     "https://picsum.photos/420/200/?temp=5"};
    private Timer timer;
    private int current_position = 0;
    private LinearLayout dotsLayout;
    private int custom_position = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_screen);

        instantiateViews();
        viewPager.setAdapter(adapter);
        createSlideShow();
    }

public void instantiateViews(){

        viewPager = findViewById(R.id.topImageSliderViewPager);
        adapter = new HomeScreenTopPagerAdapter(HomeScreen.this,urls);
        dotsLayout = findViewById(R.id.hs_dotsLayout);

    }

public void createSlideShow(){
        final Handler handler = new Handler();
        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if(current_position==Integer.MAX_VALUE)
                    current_position=0;
                viewPager.setCurrentItem(current_position++,true);
            }
        };

        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.post(runnable);
            }
        },1000,3000);
    }
}
like image 206
CS Learner Avatar asked Nov 06 '22 16:11

CS Learner


1 Answers

After spending a lot of time, i found an answer to how can i make the 1st image load rather than the 3rd one.

public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
        .
        .
        .

        GlideApp.with(context)
                .load(urls[position%urls.length])   //THE CHANGE MADE HERE, completely removed the usage of custom_position variable
                .
                .
}

Note: This only answers how to obtain the required result, it still doesn't answer how the instantiateItem() was working, showing unexpected results. I am a beginner and only an experienced person will be able to explain the error with the above method.

like image 71
CS Learner Avatar answered Nov 15 '22 08:11

CS Learner