Note that there are some explanatory texts on larger screens.

plurals
  1. POShowing specified page when view pager is first created
    primarykey
    data
    text
    <p>I have a fragment that contains a <code>ViewPager</code>. This <code>ViewPager</code> is backed by a <code>PagerAdapter</code> that uses a <code>Cursor</code>. The cursor is managed by <code>LoaderCallbacks</code>. I'm using the v4 support libraries here.</p> <p>What I want is to create the fragment and have the view pager showing a specified page, rather than starting at page 0.</p> <p>I know that <code>ViewPager</code> has a <code>setCurrentItem()</code> method, but the data may not yet be loaded when the <code>ViewPager</code> is created. What I need is to listen to the adapter for data set changes, and if that is the first such change, then call <code>setCurrentItem()</code> on <code>ViewPager</code>.</p> <p>However the <code>PagerAdapter</code> class does not export the <code>registerDataSetObserver()</code> method; it has <code>package</code> rather than <code>public</code> access (at least in the v4 support library).</p> <p>What I have done, and it seems very much like a hack to me, is the following:</p> <pre><code>class ItemPagerFragment extends SherlockFragment implements LoaderCallbacks&lt;Cursor&gt; { 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 &amp;&amp; mPager != null &amp;&amp; mAdapter.getCount() &gt; 0) { mPager.setCurrentItem(mInitialPageToShow); initialPageSet = true; } } } </code></pre> <p>There's a race condition between loading data into the adapter (in the <code>onCreate()</code> method), and creating the <code>ViewPager</code> in the <code>onCreateView()</code> method. So the current page can be set either when (a) the pager exists but data is loaded for the first time or (b) the data is loaded before the pager is created.</p> <p>I've tried to handle both cases above but I'm thinking there must be an alternative approach that is more robust (and hopefully simpler) using observers.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload