2012-01-30 77 views
10

在關於在Android文檔中使用片段的example中,當應用程序處於「雙視圖」模式時,只要應用程序需要顯示不同標題的詳細信息,就會重新創建詳細信息片段。 FragmentTransaction.replace()用於將每個舊的細節片段實例替換爲新的細節片段實例。好的更新片段而不是創建新的實例?

這是推薦的做法嗎?如果真正的意圖(不是雙關語意圖)是更新UI顯示的內容而不是UI本身,那麼創建新的UI實例並不是浪費。在我看來,創建新實例的唯一原因是如果有人想將它們添加到後臺堆棧,以便用戶可以回溯步驟。否則,是否安全/建議直接更新片段?

在該示例的情況下,這意味着沿着DetailsFragment.setShownIndex()的方向的方法。這將被稱爲傳遞新的標題索引,而不是重新創建DetailsFragment

假設我們有一個示例版本,其中一個活動同時管理兩個片段,但每次只顯示一個片段,根據需要將每個片段交換出來。活動創建每個片段的實例,保留每個片段的引用,然後根據需要簡單地添加或移除這兩個實例可以嗎?

這樣做的一個可能粘性後果是,當標題片段處於resumed狀態(即在'前景'中)時,選擇標題將導致在細節片段處於中時調用DetailsFragment.setShownIndex()stopped狀態。

好主意?餿主意?

在此先感謝。

回答

5

就像你說的那樣,創建新Fragment實例的主要原因是爲了方便使用back棧。重複使用現有片段也是絕對安全的(使用FragmentManager.findFragmentById()FragmentManager.findFragmentByTag()查看)。有時你需要充分利用片段方法,如isVisible()isRemoving()等,所以當DetailsFragmentstopped時,您不會非法引用UI組件。

無論如何在你提出的單窗格活性與2個片段,您的setShownIndex方法可以在其在onCreateViewonActivityCreated加載DetailsFragment設置一個私有字段。當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(); 

在兩種情況下,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

會更有幫助,如果您提供英語評論 – 2016-05-14 20:12:48

+0

我很抱歉,我是意大利人。 – 2016-05-15 08:13:59

相關問題