Mostrando a página especificada quando o pager de exibição é criado pela primeira vez
Eu tenho um fragmento que contém umViewPager
. esteViewPager
é apoiado por umPagerAdapter
que usa umCursor
. O cursor é gerenciado porLoaderCallbacks
. Estou usando as bibliotecas de suporte da v4 aqui.
O que eu quero é criar o fragmento e ter o pager de exibição mostrando uma página especificada, em vez de começar na página 0.
Eu sei dissoViewPager
tem umsetCurrentItem()
método, mas os dados podem ainda não ser carregados quando oViewPager
é criado. O que eu preciso é ouvir o adaptador para alterações no conjunto de dados, e se essa for a primeira dessas mudanças, ligue parasetCurrentItem()
emViewPager
.
No entanto, oPagerAdapter
classe não exporta oregisterDataSetObserver()
método; tempackage
ao invés depublic
acesso (pelo menos na biblioteca de suporte v4).
O que eu fiz, e parece muito com um hack para mim, é o seguinte:
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;
}
}
}
Há uma condição de corrida entre o carregamento de dados no adaptador (noonCreate()
método) e criando oViewPager
noonCreateView()
método. Portanto, a página atual pode ser definida quando (a) o pager existe, mas os dados são carregados pela primeira vez ou (b) os dados são carregados antes de o pager ser criado.
Eu tentei lidar com os dois casos acima, mas estou pensando que deve haver uma abordagem alternativa que seja mais robusta (e esperançosamente mais simples) usando observadores.