问题描述
我有一个包含 ViewPager
片段。这 ViewPager
被支持的 PagerAdapter
一个使用光标
。光标由 LoaderCallbacks
管理。我使用的是V4支持库在这里。
I have a fragment that contains a ViewPager
. This ViewPager
is backed by a PagerAdapter
that uses a Cursor
. The cursor is managed by LoaderCallbacks
. I'm using the v4 support libraries here.
我要的是创建片段,并有观点寻呼机显示一个指定的页面,而不是从0开始的页面。
What I want is to create the fragment and have the view pager showing a specified page, rather than starting at page 0.
我知道 ViewPager
有一个 setCurrentItem()
方法,但该数据可能还没有被加载时, ViewPager
创建。我需要的是倾听的数据集变化的适配器,如果这是第一个这样的变化,然后调用 setCurrentItem()
在 ViewPager
。
I know that ViewPager
has a setCurrentItem()
method, but the data may not yet be loaded when the ViewPager
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 setCurrentItem()
on ViewPager
.
然而 PagerAdapter
类不导出 registerDataSetObserver()
方法;它具有包
,而不是公开
接入(至少在V4支持库)。
However the PagerAdapter
class does not export the registerDataSetObserver()
method; it has package
rather than public
access (at least in the v4 support library).
我做了什么,它似乎非常像一个黑客对我来说,是这样的:
What I have done, and it seems very much like a hack to me, is the following:
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;
}
}
}
有装载数据之间的竞争条件插入适配器(在的onCreate()
法),和创建 ViewPager
在 onCreateView()
方法。所以当前页面可以设置或者当(a)存在的寻呼机,但数据被装载在第一次或(b)在创建该寻呼机之前加载数据
There's a race condition between loading data into the adapter (in the onCreate()
method), and creating the ViewPager
in the onCreateView()
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.
我试着处理这两种情况同上,但我想一定有使用观察家另一种方法是更强大的(希望更简单)。
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.
推荐答案
等到 initLoader
,直到寻呼机存在后,检查布尔标志,做好 setCurrentItem
仅在第一次 onLoadFinished
被称为:
Wait to initLoader
until after the pager exists, check the boolean flag and do setCurrentItem
only the first time onLoadFinished
is called:
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;
}
}
}
注:本段假定V13支持库,但它应该是相同的V4 的
这篇关于显示指定页面首次创建视图寻呼机时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!