Android-ViewPager адаптер, установить основной элемент перед адаптером экземпляра

Я знаю, что я могу сделать

 viewPager.setCurrentItem(position) 

чтобы установить мой пейджер просмотра в нужное положение. Мой вопрос в том, Могу ли я сделать это до создания экземпляра адаптера.

это означает, что если я делаю

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

элемент 0-это первая сборка, и после этого элемент в нужной позиции также является сборкой. Что занимает вдвое больше времени...в моем адаптере каждый элемент требует довольно много работы для сборки, поэтому было бы лучше избегать 0-позиционного элемента для сборки, если это возможно. Возможно, путем передачи желаемой позиции в качестве аргумента при создании экземпляра адаптера...?

любой способ сделать это?

6 ответов


вы можете обмануть viewpager для запуска в заданной позиции до установки адаптера, вызвав onRestoreInstanceState, например:

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);

Если время и работа-это то, о чем вы беспокоитесь, я бы попытался избежать создания страницы в позиции 0, пока не будет построен желаемый. Вы можете использовать переменную, скажем, " desiredPageHasBeenBuilt "в вашем адаптере, при запросе элемента в позиции 0 вы можете вернуть" пустую страницу", если переменная desiredPageHasBeenBuilt ложна, когда ваша желаемая страница была построена, установите переменную в true, и страница 0 может быть построена.


вы можете просто установить пустой адаптер, и после этого установите свой реальный адаптер таким образом, вы "обманете" viewpager, и вы хотите загрузить любые данные, которые вы не хотите.

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);

для решения, которое работает в Android M, а также более старых версиях, используйте отражение следующим образом:

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);

использование отражения безопасно, потому что вы контролируете ViewPager реализация (она включена в ваше приложение).

если вы используете Proguard, то вам нужно включить в его конфигурацию следующее:

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

или mRestoredCurItem будет переименован Proguard.


может это не тот ответ, который вы ищете, но вы пробовали его, как он был разработан? Не начинайте тяжелую работу над фрагментом страницы, прежде чем он будет прикреплен к экрану. Таким образом, вы получите то поведение, которое вы хотите без взлома реализации android.


вы можете сделать этот трюк:

рефакторинг всей вашей тяжелой работы в функцию, потому что создание fragment не занимает много времени и выполняет функцию только тогда, когда пользователь увидит ее, вызвав эту функцию внутри OnPageChangeListener слушатель и на

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