问题描述
我有活动:
`<RelativeLayout>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button/>
<Button/>
</RelativeLayout>`
这里面的容器,这取决于哪个按钮pressed出现碎裂或FragmentB。这些片段 容器的作为嵌套的子片段。即在每一个片段包含它自己的导航堆栈
Inside this container, depending on which button pressed appear FragmentA or FragmentB. These fragments are containers for nested child-fragments. I.e. in each fragment contains its own navigation stack.
在活动的onCreate我这些实例2片段:
In onCreate of Activity I instantiate these 2 fragments:
碎裂=(FragmentContainer)Fragment.instantiate(这一点,FragmentContainer.class.getName());
fragmentB =(FragmentContainer)Fragment.instantiate(这一点,FragmentContainer.class.getName());
然后,我继续替换一个对方:
Then, I'm continue replacing one each other:
最后FragmentTransaction fragmentTransaction = getSupportFragmentManager()调用BeginTransaction()
.replace(R.id.container,片段);
.commitAllowingStateLoss();
到目前为止,一切都很好,一切正常。但
So far, so good, everything is working. BUT
问题:
我每次更换碎裂由fragmentB(和反之亦然) - getChildFragmentManager()破坏它的导航堆栈和碎裂/ B开始从头每次不与嵌套的片段就被替换前载
Every time I replace fragmentA by fragmentB (and vice verse) - getChildFragmentManager() destroy its navigation stack and fragmentA/B starts every time from scratch, not with the nested fragment it contained before being replaced.
任何想法?它是可行的,至少?
有一个灿烂的日子,
康斯坦丁
Any ideas? Is it doable, at least?Have a brilliant day,Konstantin
推荐答案
所以,这就是我解决了这个:
So that's how I solved this:
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]);
}
}
}
FragmentContainer.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的航海模型:)
Hopefully, it would help someone, who's trying to copy instagram navigation model :)
这篇关于保留getChildFragmentManager导航堆栈删除并重新添加片段后,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!