Display the specified page the first time you create a pager view

I have a fragment containing a ViewPager . This ViewPager supported by the PagerAdapter , which uses Cursor . The cursor is controlled by LoaderCallbacks . I use v4 support libraries here.

I want to create a fragment and show the presentation pager with the specified page, and not start from page 0.

I know that ViewPager has a setCurrentItem() method, but the data may not load yet when creating the ViewPager . I need to listen to the adapter for changes to the dataset, and if this is the first such change, call setCurrentItem() on the ViewPager .

However, the PagerAdapter class PagerAdapter not export the registerDataSetObserver() method; it has package , not public access (at least in the v4 support library).

What I did, and it looks like a hack to me, is this:

 class ItemPagerFragment extends SherlockFragment implements LoaderCallbacks<Cursor> { private CursorPagerAdapter mAdapter; private ViewPager mPager; private int mInitialPageToShow; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAdapter = new CursorPagerAdapter() { @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); setInitialPageIfRequired(); } }; getActivity().getSupportLoaderManager().initLoader(LOADER_ID, null, this); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { View view = inflater.inflate(R.layout.items_pager, group, false); mPager = (ViewPager) view.findViewById(R.id.pager); mPager.setAdapter(mAdapter); setInitialPageIfRequired(); return view; } private boolean initialPageSet = false; private synchronized void setInitialPageIfRequired() { // Set the current page of the pager if (a) this is the // first time attempting to set the page and (b) the // pager exists and (c) the adapter has data. if (!initialPageSet && mPager != null && mAdapter.getCount() > 0) { mPager.setCurrentItem(mInitialPageToShow); initialPageSet = true; } } } 

There is a race condition between loading data into the adapter (in the onCreate() method) and creating a ViewPager in the onCreateView() method. Thus, the current page can be set when (a) a pager exists, but data is loaded for the first time or (b) data is loaded before the pager is created.

I tried to handle both cases above, but I think there should be an alternative approach, more reliable (and, hopefully, simpler) using observers.

+2
android android-viewpager android-pageradapter android-cursorloader
Dec 11
source share
1 answer

Wait until initLoader until a pager appears, check the boolean flag and setCurrentItem only the first time onLoadFinished :

 class ItemPagerFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { private CursorPagerAdapter mAdapter; private ViewPager mPager; private int mInitialPageToShow; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { View view = inflater.inflate(R.layout.items_pager, group, false); mPager = (ViewPager) view.findViewById(R.id.pager); mAdapter = new CursorPagerAdapter(getFragmentManager()); mPager.setAdapter(mAdapter); return view; } @Override public void onViewCreated(View view, Bundle saved) { super.onViewCreated(view, saved); ... getLoaderManager().initLoader(LOADER_ID, null, this); } @Override public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { mAdapter.swapCursor(cursor); setInitialPageIfRequired(); } private boolean initialPageSet = false; private synchronized void setInitialPageIfRequired() { // Set the current page of the pager if (a) this is the // first time attempting to set the page and (b) the // pager exists and (c) the adapter has data. if (!initialPageSet && mPager != null && mAdapter.getCount() > 0) { mPager.setCurrentItem(mInitialPageToShow); initialPageSet = true; } } } 

Note: this snippet assumes the v13 support library, but it should be the same for v4.

+3
Jun 11 '14 at 23:15
source share



All Articles