1

私のアプリケーションには、向きとデバイスのサイズによって異なるレイアウトがあります。大型のデバイスでは、同時に表示される 2 つのビューで構成されます。小さいデバイスでは、レイアウトは、ユーザーが 2 つのペインを切り替えることができる ViewPager です。これは典型的なパターンです。

問題は、ViewPager が固執しているように見え、そのフラグメントを保持していることです。ただし、TextRenderFragment には同じフラグメント インスタンスが保持されません。代わりに、クラスが毎回新しく作成されているように見えます。フラグメントは ViewPager 内に保持されるため、最終的に 2 セットのコンテンツ ビューが作成されます。ビューの 2 つのセットがバンドルを共有しないため、状態の復元に問題が発生します。

これは非常に一般的なパターンであるため、これを適切に行う方法についての議論を見つけることを期待していましたが、できませんでした。ViewPager のフラグメントを手放すか、向きに応じて ViewPager と静的レイアウトの両方で同じコンテンツ フラグメント インスタンスを使用する方法を見つけたいと思います。

構造は次のようになります。

@Override
public View onCreateView(final LayoutInflater inflater,
        final ViewGroup container, final Bundle saved_instance_state) {

    if (saved_instance_state != null) {
        current_book = saved_instance_state.getInt("book");
        current_chapter = saved_instance_state.getInt("chapter");
    }

    // Inflate the layout for this fragment
    final View v = inflater.inflate(R.layout.fragment_text_render,
            container, false);

    _configure_content_fragments(v);
    return v;
}

private void _configure_content_fragments(final View v) {
    final ViewPager vp = (ViewPager) v.findViewById(R.id.tr_view_pager);
    bl = new DocLoader();

    boolean add_fragments = false;
    final FragmentManager mgr = getFragmentManager();
    primary_content_fragment = (PrimaryContent) mgr
            .findFragmentByTag("primary_content_fragment");
    secondary_content_fragment = (SecondaryContent) mgr
            .findFragmentByTag("secondary_content_fragment");

    if (primary_content_fragment == null) {
        primary_content_fragment = new PrimaryContent();
        secondary_content_fragment = new SecondaryContent();
        primary_content_fragment.setNavLocation(current_book,
                current_chapter);
        add_fragments = true;
    }

    if (add_fragments && vp == null) {
        final android.support.v4.app.FragmentTransaction tx = getFragmentManager()
                .beginTransaction();
        tx.add(R.id.tr_primary_content_container, primary_content_fragment,
                "primary_content_fragment");
        tx.add(R.id.tr_secondary_content_container,
                secondary_content_fragment, "secondary_content_fragment");
        tx.commit();
    }

}

ViewPager の初期化は次のようになります。

@Override
public void onStart() {
    super.onStart();
    _configure_view_pager(getView());
}
 private void _configure_view_pager(final View v) {
    final ViewPager vp = (ViewPager) v.findViewById(R.id.tr_view_pager);

    if (vp != null) {
        final FragmentManager mgr = getFragmentManager();
        final FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(
                mgr) {

            @Override
            public int getCount() {
                return 2;
            }

            @Override
            public Fragment getItem(final int item) {
                switch (item) {
                case 0:
                    return primary_content_fragment;
                case 1:
                    return secondary_content_fragment;
                }

                return null;
            }
        };

        vp.setAdapter(adapter);
    }
}
4

1 に答える 1