Android - ViewPager adapter, sets the primary element before creating the adapter

I know what I can do

viewPager.setCurrentItem(position) 

to set the viewing player to the desired position. My question is how and how can I do this before the adapter is instantiated.

That means if I do

 pagerAdapter = new ViewPagerAdapter(arg1,arg2....); viewPager.setAdapter(pagerAdapter); viewPager.setCurrentItem(position); 

item 0 is first created, and after that the item in the right place is also created. Which takes twice as much time ... In my adapter, each element requires a lot of work to be able to build, so it would be better to avoid the position of position 0, which will be built if possible. Perhaps passing the desired position as an argument when creating the adapter ...?

How to do it?

+6
source share
7 answers

You can trick the viewer to run at a given position before the adapter is installed by calling onRestoreInstanceState, for example:

 int currentItem = 5; Parcel parcel = Parcel.obtain(); writeParcelable(BaseSavedState.EMPTY_STATE, 0); writeInt(currentItem); writeParcelable(null, 0); setDataPosition(0); SavedState savedState = ViewPager.SavedState.CREATOR.createFromParcel(parcel); mPager.onRestoreInstanceState(savedState); mPager.setAdapter(mAdapter); 
+1
source

Based on the current implementation , if there is no adapter, setCurrentItem() ignored.

+3
source

If time and labor is what you are worried about, I would try to avoid creating the page at position 0 until the desired one is created. You can use a variable that allows you to say “wishPageHasBeenBuilt” in your adapter, when you request an item at position 0, you can return a “blank page” if wishPageHasBeenBuilt is false when your desired page has been created, set the variable to true and page 0 can be built.

+3
source

You can simply install the empty adapter and after that install the real adapter in such a way that you will "cheat" the viewpager and want to load any data that you do not want.

 this.viewPager.setAdapter(new PagerAdapter() { @Override public int getCount() { return 0; } @Override public boolean isViewFromObject(View view, Object object) { return false; } }); this.viewPager.setCurrentItem(imagePosition, false); this.viewPager.setAdapter(adapter); this.viewPager.setCurrentItem(imagePosition, false); 
+3
source

For a solution that works in Android M, as well as in older versions, use reflection as follows:

 int currentItem = 5; // Set initial position first... Field field = ViewPager.class.getDeclaredField("mRestoredCurItem"); field.setAccessible(true); field.set(mPager, currentItem); // ...and then set adapter mPager.setAdapter(adapter); 

Using reflection is safe because you control the implementation of ViewPager (it is part of your application).

If you are using Proguard, you need to include the following in its configuration:

 -keepclassmembers class android.support.v4.view.ViewPager { private int mRestoredCurItem; } 

or the mRestoredCurItem field will be renamed to Proguard.

+1
source

you can do this trick:

reorganize all your hard work into a function, because creating a fragment does not take much time and only performs a function when the user sees it, calling this function inside the OnPageChangeListener listener and in

 @Override public void onPageSelected(int position){ // call your function that do heavy working } 
0
source

This may not be the answer you are looking for, but have you tried to use it the way it was designed? Do not start hard work with a page fragment before it is attached to the screen. This way you get the desired behavior without hacking the android version.

0
source

Source: https://habr.com/ru/post/975861/


All Articles