web-dev-qa-db-ja.com

OnCreateViewが複数回呼び出される/ ActionBarとフラグメントの操作

きれいなActionBarタブを使用できるように、アプリの一部をアクティビティからフラグメントに切り替えました。

しかし、移行を完了した後、別のタブに切り替えるたびに、そのフラグメントが再び作成されるという問題に遭遇しました。タブにアクセスするたびに、onCreateとonCreateViewの両方が呼び出されます。

4つのタブがあり、各タブはこれらのフラグメントの1つを開くためのものです。

Fragment ShopFragment = new WebActivity();
Fragment SearchFragment = new SearchActivity(context);
Fragment StoreFragment = new StoreLocatorActivity(context, this);
Fragment BlogsFragment = new BlogsActivity(context, this);

リスナー用の私のコードは次のとおりです。

    class MyTabsListener implements ActionBar.TabListener {
        public Fragment fragment;

        public MyTabsListener(Fragment fragment) {
            this.fragment = fragment;
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            ft.hide(fragment);
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            ft.replace(R.id.fragment_container, fragment);
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {          

        }

    }

誰かが私を正しい方向に向けてくれますか?

40
Sorin Cioban

FragmentTransaction.replace(...) を呼び出すと、Androidは一連の FragmentTransaction.remove(...) を効果的に実行します(そのコンテナに現在追加されているすべてのフラグメントの場合)および FragmentTransaction.add(...) (指定されたフラグメントの場合)FragmentManagerからフラグメントを削除すると、フラグメントは最も顕著なのは、フラグメントを再度追加すると、すべてのビューがリセットされることです。注:同じフラグメントインスタンスを再利用しているため、フラグメントはインスタンス変数の値を保持します。

この問題の解決策の1つは、切り替え時に FragmentTransaction.detach(Fragment) および FragmentTransaction.attach(Fragment) を使用することです。これにより、フラグメントビューが再作成されます(onDestroyView()onCreateView()が呼び出されます)が、インスタンスステートバンドルが保存され、呼び出し間でビューステートが返されます維持することができます。これは、フラグメントを切り替えようとするときに FragmentPagerAdapter がとるアプローチです。

または、フラグメントの破棄を許可することもできますが、フラグメントの保存状態は個別に維持できます。これにより、スイッチング時間が遅くなりますが、使用するメモリが少なくなります。注意すべきメソッドは、追加/削除に関連して FragmentManager.saveFragmentInstanceState(Fragment) および FragmentManager.setInitialSavedState(Fragment.SavedState) になります。これは、 FragmentStatePagerAdapter によるアプローチです。

実装のヒントについては、 FragmentPagerAdapterのソース および FragmentStatePagerAdapterのソース をご覧ください。

47
antonyt

show / hide オプションがあり、フラグメントを再描画/再作成する必要がなく、onCreate()およびonCreateView()再度呼び出されることはありません。

7