显示指定页面首次创建视图寻呼机时 [英] Showing specified page when view pager is first created

查看:174
本文介绍了显示指定页面首次创建视图寻呼机时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 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

这篇关于显示指定页面首次创建视图寻呼机时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆