2

我有一个包含ViewPager. 这ViewPagerPagerAdapter使用 a 的 a支持Cursor。游标由 管理LoaderCallbacks。我在这里使用 v4 支持库。

我想要的是创建片段并让视图寻呼机显示指定的页面,而不是从第 0 页开始。

我知道ViewPager有一个setCurrentItem()方法,但是创建时数据可能尚未加载ViewPager。我需要的是监听数据集更改的适配器,如果这是第一次这样的更改,然后调用setCurrentItem().ViewPager

但是PagerAdapter该类不导出该registerDataSetObserver()方法;它拥有package而不是public访问(至少在 v4 支持库中)。

我所做的,对我来说似乎很像一个黑客,如下:

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()方法中)和ViewPageronCreateView()方法中创建之间存在竞争条件。因此,可以在 (a) 寻呼机存在但第一次加载数据或 (b) 在创建寻呼机之前加载数据时设置当前页面。

我已经尝试处理上述两种情况,但我认为必须有一种替代方法,使用观察者更强大(并且希望更简单)。

4

1 回答 1

3

等到initLoader寻呼机存在后,检查布尔标志并只调用setCurrentItem第一次: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;
        }
    }
}

注意:此代码段假定 v13 支持库,但它应该与 v4 相同。

于 2014-06-11T23:15:40.960 回答