2011-12-08 13 views
9

私のプロジェクトで互換性パッケージv4を使用していますが、ビューから削除した後にFragmentの周りに問題があります。私はActivityの2つのフラグメントを表示しています...左側のメニューフレーム、右側のコンテンツペイン。メニューフレームには、表示可能な3つの異なるメニュー(フラグメント)があります。以前に表示されたフラグメントを復元するにはどうすればよいですか?

これは私がメニューフラグメントを交換しています方法です:

public void showMenuFragment(Fragment fragment, String tag) { 

     showFragment(R.id.menu_frame, fragment, tag, false); 
     setLastMenuPushed(tag); 
    } 

protected void showFragment(int resId, Fragment fragment, String tag, boolean addToBackStack) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 

     if (fragmentManager.findFragmentByTag(tag) != null && fragment.isAdded()) { 
      transaction.remove(fragment); 
     } 

     transaction.replace(resId, fragment, tag).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).setBreadCrumbShortTitle(tag); 

     if (addToBackStack) { 
      transaction.addToBackStack(tag); 
     } 

     transaction.commit(); 
    } 

メニューFragment sが、それが表示される前にロードするデータを必要とするので、私は、ローディングスピナーを示しています。初めてロードされると、Activityが完了していない限り、2回目にロードする必要はありません。

私はFragmentManager.findFragmentByTag(String tag)を使用してFragmentに合格しようとするが、それは常にnullですので、私は、私は別のメニューを表示する新しいFragmentたびに行う必要がありshowMenuFragment(...)を呼び出します。

私の質問は、これらのメニューを他のメニューに置き換えた後、これらのメニューをどう保持しますか? Fragmentへの手動参照を避けたいのですが、デバイスを回転させると、Activityクラスのインスタンスが破棄され、それらの参照が失われるためです。

編集:もっと簡単に言えば、FragmentManagerは前のFragmentをバックスタックに追加することなく追跡してほしいです。私は戻るボタンを押して、表示されている前のメニューを見たくない。

答えて

13

ちょうど分かりました。新しいものを追加するときにフラグメントを削除するのではなく、単にそれらを非表示にして、再度表示したいときに表示します。

public void showMenuFragment(Fragment fragment, String tag, boolean addToBackStack) { 

     showFragment(R.id.menu_frame, fragment, tag, getLastMenuPushed(), addToBackStack); 
     setLastMenuPushed(tag); 
} 

protected void showFragment(int resId, Fragment fragment, String tag, String lastTag, boolean addToBackStack) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 

     if (lastTag != null) { 
      Fragment lastFragment = fragmentManager.findFragmentByTag(lastTag); 
      if (lastFragment != null) { 
       transaction.hide(lastFragment); 
      } 
     } 

     if (fragment.isAdded()) { 
      transaction.show(fragment); 
     } 
     else { 
      transaction.add(resId, fragment, tag).setBreadCrumbShortTitle(tag); 
     } 

     if (addToBackStack) { 
      transaction.addToBackStack(tag); 
     } 

     transaction.commit(); 
} 
+3

これを振り返ってみると、より良い解決策は、アクティビティからフラグメントを「切り離し」、クラス内のハードリファレンスを保持することだったと思います。 –

+0

detach vs hideのメリットは何ですか?ビューを破壊することは本当の違いをもたらしますか?フラグメント全体を再ロードせずに復元する良い方法はありますか? – ben

+0

@ben Detachは画面からビュー階層を削除します。これはより環境に優しいアプローチです。ほとんどのビューは、フラグメントから削除されたときにインスタンス状態を保存するという良い仕事をしています。したがって、再接続すると大したことはありません。 –

0

これが可能かどうかわかりません。 FragmentManagerは彼のBackStackでFragmentsにのみ世話をします。しかし、FragmentActivityonBackButtonPressedを実装させ、カスタム動作をさせる場合は、バックボタン押下の問題を回避することができます。 Fragmentsに委譲するか、アプリロジックに応じて別のFragmentを表示することができます

関連する問題