2015-02-06 43 views
1

後我具有活性:保留getChildFragmentManager導航堆棧移除並重新添加片段

`<RelativeLayout> 
    <FrameLayout 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
    <Button/> 
    <Button/> 
</RelativeLayout>` 

這裏面的容器中,這取決於哪一個按鈕按下出現FragmentA或FragmentB。對於嵌套的子片段,這些片段是容器。即在每個片段中都包含自己的導航堆棧。

在活動的onCreate我舉例說明這些2個片段:

fragmentA = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName()); fragmentB = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());

然後,我繼續更換一個對方:

final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction() .replace(R.id.container, fragment); .commitAllowingStateLoss();

到目前爲止,一切都很好,一切都工作中。 BUT

問題:

每次更換fragmentA由fragmentB(和反之亦然) - getChildFragmentManager()破壞其導航堆棧和fragmentA/B開始從頭每次,不與嵌套片段它在被替換之前包含。

任何想法?至少它可行嗎? 有一個燦爛的一天, 康斯坦丁

回答

2

所以這就是我如何解決這樣的:

MainActivity.xml

<RelativeLayout> 
    <FrameLayout 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</RelativeLayout> 

MainActivity.java

public class MainActivity extends FragmentActivity { 

    final FragmentContainer [] fragmentContainers = new FragmentContainer[3]; 
    int currentTabIndex = -1; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     final FragmentMetaData [] fragmentContainersMetaData = { 
       new FragmentMetaData(FragmentA.class.getName(), null), 
       new FragmentMetaData(FragmentB.class.getName(), null), 
       new FragmentMetaData(FragmentC.class.getName(), null) 
     }; 

     for (int i = 0; i < fragmentContainers.length; i++) { 
      fragmentContainers[i] = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName()); 
      fragmentContainers[i].addMetaData(fragmentContainersMetaData[i]); 
     } 

     tabPageNavigationSelection(0); 
    } 

    void replaceFragmentBy(final Fragment fragment) { 
     FragmentManager fragmentManager = getSupportFragmentManager();      
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
     fragmentTransaction.replace(R.id.container, fragment); 
     fragmentTransaction.commitAllowingStateLoss(); 
    } 

    // Method to switch between tabs 
    void tabPageNavigationSelection (final int index) { 
     if (currentTabIndex == index) { 
      fragmentContainers[currentTabIndex].clearStackExceptRootFragment(); 
     } else { 
      currentTabIndex = index; 
      replaceFragmentBy(fragmentContainers[currentTabIndex]); 
     } 
    } 
} 

FragmentC ontainer.xml

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:background="@color/lightest_gray" 
    android:id="@+id/nestedContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

FragmentContainer.java

public final class FragmentContainer extends Fragment { 
    private final List<FragmentMetaData> fragmentMetaDataStack = new ArrayList<>(); 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     initialize(inflater, container, R.layout.fragment_container); 

     for (FragmentMetaData metaData : fragmentMetaDataStack) { 
      showNestedFragment(Fragment.instantiate(getActivity(), metaData.className, metaData.fragmentBundle), fragmentMetaDataStack.indexOf(metaData) > 0, true); 
     } 

     return getFragmentView(); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (getChildFragmentManager().getFragments() == null){ 
      return; 
     } 

     int stackDepth = getChildFragmentManager().getFragments().size(); 
     if (stackDepth > 0 && fragmentMetaDataStack.size() < stackDepth && 
       getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size() - 1) != null) { 
      getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size()-1).onResume(); 
     } 
    } 

    public void showNestedFragment(final Fragment fragment, final boolean addToBackStack, final boolean isRestoring) { 
     final FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.nestedContainer, fragment); 
     if (addToBackStack) { 
      fragmentTransaction.addToBackStack(null); 
     } 

     if (!isRestoring) { 
      fragmentMetaDataStack.add(new FragmentMetaData(fragment.getClass().getName(), fragment.getArguments())); 
     } 

     fragmentTransaction.commitAllowingStateLoss(); 
    } 

    public void onBackPressed() { 
     if (getChildFragmentManager().getBackStackEntryCount() > 0) { 
      getChildFragmentManager().popBackStack(); 
      fragmentMetaDataStack.remove(fragmentMetaDataStack.size() - 1); 
     } else { 
      getActivity().finish(); 
     } 
    } 

    public void addMetaData(FragmentMetaData metaData) { 
     fragmentMetaDataStack.add(metaData); 
    } 

    public void clearStackExceptRootFragment() { 
     getChildFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); 
     while (fragmentMetaDataStack.size() > 1) { 
      fragmentMetaDataStack.remove(1); 
     } 
    } 
} 

我們希望,這將幫助別人,誰試圖複製Instagram的導航模式:)

+0

如何使用'showNestedFragment'從嵌套的'片段'? – 2016-08-08 08:26:17