ViewPager имеет плохие данные смещения после поворота экрана, когда текущая страница не первая

Структура приложения:

Мое приложение имеет одну FragmentActivity , а FragmentActivity содержит Fragment котором размещается ViewPager . ViewPager имеет адаптер, который подклассы FragmentStatePagerAdapater , и этот адаптер переопределяет getItem() чтобы вернуть новый фрагмент, основанный на позиции; getCount() установлен всегда для возврата 2.

Проблема:

Приложение работает очень хорошо, пока не произойдет одна из двух вещей: вращение происходит, когда ViewPager отображает второй фрагмент, или если в onResume() , ViewPager предлагается прокручивать страницу на другую, первую. Насколько я могу судить, эти сценарии идентичны. Когда происходит одно из этих событий, прокрутка прекратилась, и видимый фрагмент является вторым из фрагментов, управляемых ViewPager, onPageScrolled(int, float, int) обратный вызов onPageScrolled(int, float, int) вызывается с аргументом «position», все еще находящимся в '0' (Это должно быть 1), а аргумент «positionOffset» установлен в «1» (который находится вне диапазона [0,1], как обещалось в документах). Я прокрутил код ViewPager и обнаружил, что boolean pageScrolled(int xpos) переходит от boolean pageScrolled(int xpos) со значениями в диапазоне от [0,940] (0 на первой странице, а затем от 940 на втором) до вызова Со значениями в диапазоне [-940,0] (-940 на первом, 0 на втором). Если ViewPager был сброшен, чтобы думать, что вторая страница была первой страницей, тогда это действительно имеет смысл (вроде), хотя это совсем не то, что я хочу.

Некоторый код:

ViewPagerFragment (размещает ViewPager). MyViewPager – это всего лишь копия / вставка ViewPager библиотеки поддержки; Я хотел распечатать некоторые данные из своих частных методов.

 public class ViewPagerFragment extends Fragment implements MyViewPager.OnPageChangeListener{ @InjectView(R.id.view_pager) MyViewPager viewPager; @DebugLog public ViewPagerFragment() { setRetainInstance(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_view_pager, container, false); ButterKnife.inject(this,view); Log.d("onCreateView()","ViewPagerFragment = "+this.toString()); return view; } @Override public void onResume() { super.onResume(); setupPager(); } void setupPager(){ if(viewPager != null) { if (viewPager.getAdapter() == null) { viewPager.setAdapter(new MyFragmentAdapter(getChildFragmentManager())); } viewPager.setOnPageChangeListener(this); viewPager.setPageMargin(40); } } @Override @DebugLog public void onDestroyView() { super.onDestroyView(); viewPager.setOnPageChangeListener(null); ButterKnife.reset(this); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if(positionOffset == 1f){ Log.d("onPageScrolled","position offset == 1 and position == "+position+". That's bad!"); } else if(position == 1){ Log.d("onPageScrolled","position offset == "+positionOffset+" and position == 1. That's good!"); } } public static class MyFragmentAdapter extends FragmentStatePagerAdapter{ public MyFragmentAdapter(FragmentManager fm) { super(fm); } @Override @DebugLog public Fragment getItem(int position) { return PageFragment.newInstance(position); } @Override public int getCount() { return 2; } } 

}

Мой вопрос, если это не подразумевается, – «Что я сделал, чтобы испортить мой ViewPager и как его исправить?» Удаление setRetainInstance() , очевидно, приведет к нормальному состоянию вещей, но затем я потеряю свое место в ViewPager. Удаление setRetainInstance() а затем использование Bundle savedInstanceState для сохранения позиции ViewPager также не работает (как упоминалось в начале моего сообщения).

Заранее спасибо!

Кажется, что ошибка в ViewPager после вращения.

Я вычисляю scrollX (смещение) текущей страницы, и всегда будет 0, когда выполняется прокрутка одной страницы.

Тем не менее, он достигает 1 или X (вокруг ширины страницы, 938 ~ 9, если ширина страницы равна 940) после вращения.

У меня возникли проблемы с onPageScrolled когда устройство повернулось, и я решил их, снова вызвав setAdapter на setAdapter вызове вращения, например onConfigurationChanged .

Вот несколько блоков кода. Device – это мой пользовательский класс.

 public void configOnOrientationChange() { if (Device.isPortrait(getContext())) { configOnPortraitOrientation(); } else if (Device.isLandscape(getContext())) { configOnLandscapeOrientation(); } int currentItem = mViewPager.getCurrentItem(); if (mPagerAdapter != null) { mViewPager.setAdapter(mPagerAdapter); mViewPager.setCurrentItem(currentItem); } } 

Надеюсь это поможет.