2

を含むフラグメントがありますViewPager。これViewPagerは、PagerAdapterを使用するによってサポートされていますCursor。カーソルは によって管理されLoaderCallbacksます。ここでは v4 サポート ライブラリを使用しています。

私が望むのは、フラグメントを作成し、ページ 0 から開始するのではなく、ビュー ページャーに指定したページを表示させることです。

ViewPagerメソッドがあることは知ってsetCurrentItem()いますが、 が作成されたときにデータがまだロードされていない可能性がありますViewPager。必要なのは、データ セットの変更についてアダプターをリッスンすることです。それが最初の変更である場合は、setCurrentItem()onを呼び出します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()作成の間に競合状態があります。したがって、現在のページは、(a) ページャーが存在するがデータが初めてロードされる場合、または (b) ページャーが作成される前にデータがロードされる場合に設定できます。ViewPageronCreateView()

上記の両方のケースを処理しようとしましたが、オブザーバーを使用して、より堅牢な (できればより単純な) 代替アプローチが必要であると考えています。

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 に答える