2012-01-30 12 views
10

Androidのドキュメントでフラグメントを使用している場合のexampleでは、アプリケーションが「デュアルビュー」モードのときに、アプリケーションが別のタイトルの詳細を表示する必要があるときはいつでも、詳細フラグメントが再作成されます。 FragmentTransaction.replace()は、古いディテール・フラグメントの各インスタンスを新しいインスタンスにスワップアウトするために使用されます。新しいインスタンスを作成するのではなくフラグメントを更新することはできますか?

これは推奨される方法ですか? UI自体ではなく、UIの内容を更新することが意図されている場合は、新しいUIインスタンスを作成するのは無駄ではありませんか?新しいインスタンスを作成する唯一の理由は、バックスラックにインスタンスを追加して、ユーザーがステップをリトレースできるということだけです。さもなければ、断片を直接更新することは安全か推薦されますか?

例の場合、それはDetailsFragment.setShownIndex()の行に沿ったメソッドを意味します。これは、DetailsFragmentを再作成する代わりに、新しいタイトルインデックスを渡して呼び出されます。

例では、1つのアクティビティで両方のフラグメントを管理し、一度に1つのみを表示し、必要に応じて各フラグメントを交換しているとします。アクティビティが各フラグメントのインスタンスを作成し、それぞれの参照を保持し、必要に応じてこれらの2つのインスタンスを追加または削除するだけでよいでしょうか?

これは、タイトルフラグメントがresumed状態(つまり「フォアグラウンド」)にあるとき、タイトルを選択すると、詳細フラグメントが存在するときにDetailsFragment.setShownIndex()が呼び出されることになりますstopped状態。

いい考えですか?悪いアイデア?

ありがとうございます。

答えて

5

あなたが言ったように、新しいFragmentインスタンスを作成する主な理由は、バックスタックを使いやすくするためです。また、既存のフラグメント(FragmentManager.findFragmentById()またはFragmentManager.findFragmentByTag()のいずれかを使用して検索すること)を再利用することも完全に安全です。場合によってはisVisible(),isRemoving()などのFragmentメソッドを有効に使用する必要があるため、DetailsFragmentstoppedの場合はUIコンポーネントを不正に参照しないでください。

はとにかく2つのフラグメントとご提案シングルペインの活動に、あなたのsetShownIndex方法はonCreateViewまたはonActivityCreatedにロードされているDetailsFragmentでプライベートフィールドを設定することができます。両方の場合において

例えば、

DetailsFragment df = getFragmentManager().findFragmentByTag("details"); 
if (df != null) { 
    df.setShownIndex(getSelectedIndex()); 
} else { 
    df = DetailsFragment.newInstance(getSelectedIndex()); 
} 
fragmentTransaction.replace(R.id.frame, df, "details").commit(); 

DetailsFragmentがコンテナに追加されるときに、DFが新たに作成または再使用されるかどうかを、onCreateViewonActivityCreatedが呼び出されます。

バックスタックが必要な場合は、新しいインスタンスを作成することを強くお勧めします。それ以外の場合は、DetailsFragmentのコンテンツ用に独自のバックスタックを実装するだけです。

0

私は、次のコードを試してみました、それが私の作品:

private void replaceFragment(Class fragmentClass, String FRAGMENT_NAME, android.support.v4.app.FragmentManager fragmentManager) { 

    Fragment fragment = null; 
    String backStateName = fragmentClass.getName(); // nome della classe del Fragment 

    Log.d("Fragment: ", "Creazione Fragment: "+backStateName); 


    Boolean fragmentExit = isFragmentInBackstack(fragmentManager, backStateName); 


    if (fragmentExit) { //Il Fragment è presente nello stacback 

     // Fragment exists, go back to that fragment 
     //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow 
     fragmentManager.popBackStackImmediate(fragmentClass.getName(), 0); 

    } else { 

     // se non esiste lo aggiungiamo 
     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // Inizializzo la transazione del Fragment 
     android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction(); 
     ft.setCustomAnimations(
       R.anim.fragment_slide_left_enter, 
       R.anim.fragment_slide_left_exit, 
       R.anim.fragment_slide_right_enter, 
       R.anim.fragment_slide_right_exit); 
     ft.replace(R.id.frameLayout_contentMain, fragment, FRAGMENT_NAME); 
     ft.addToBackStack(fragmentClass.getName()); 
     ft.commit(); 

     // Recupero il numero di Fragment presenti 
     Integer nFragment = fragmentManager.getBackStackEntryCount(); 

     Log.d("Fragment: ", "Numero di Fragment: "+nFragment); 

    } 

} 

フラグメントは、この機能を実行StackBackにすでに存在するかどうかを確認するには:

public static boolean isFragmentInBackstack(final android.support.v4.app.FragmentManager fragmentManager, final String fragmentTagName) { 
    for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) { 
     if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) { 
      return true; 
     } 
    } 
    return false; 
} 

私は、私はあなたを助けることを願っ

+0

英語でコメントを投稿した方がより役に立ちます。 –

+0

私はごめんなさい。私はイタリア語です。 –

関連する問題