Open hele-jeremy opened 3 years ago
原生的navigation跳转页面时replace替换Fragment的因此launchSingleTop只能工作在自己跳转自己页面的情况,因此在原生的情况下,机制是launchSingleTop每次都会新建一个新的页面fragment实例,并将上一个自己页面的fragment实例给popupbackstatck 出栈并且将新创建的fragment页面实例给入栈,而改为了hide的机制后, launchSingleTop不应该将老的上一个页面给出栈,而是应该 继续保持老的fragment页面实例在栈中
@hele-jeremy 感谢你的分享,经测试,上述代码可实现预期效果,且在目前已知场景下皆未产生副作用, 为此可以邀请你 pull request 上述设计吗?这可以让你的这次分享出现在贡献名单中。开源不是一个人的战斗,我们希望每位贡献者都能出现在贡献者名单。
已提交pr
<fragment android:id="@+id/DFragment" android:name="com.jlpay.navigation_lession.navigation_demo.case3.DFragment" android:label="DFragment" tools:layout="@layout/fragment_d"> <action android:id="@+id/action_DFragment_self" app:destination="@id/DFragment" app:launchSingleTop="true" />
launchSingleTop属性跳转页面在不同的手机上有不同的 表现,某些手机会闪一下,某些机型会直接显示上一级的 页面
原因为hide隐藏的其实就是DFragment,而add添加的fragment其实也是Dfragment因此在同一个FragmentTransation中隐藏和添加同一个Fragment会有问题的,if (mBackStack.size() > 0 && mFragmentManager.getFragments().size() > 0) { Log.d("Nav"," --Hide --Add"); ft.hide(mFragmentManager.getFragments().get(mBackStack.size() - 1)); ft.add(mContainerId, frag); } 我修改了FragmentNavigator的navigate方法相当是launchsingletop的情况下,不将新创建的fragmet入栈: public NavDestination navigate(@NonNull Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions, @Nullable Navigator.Extras navigatorExtras) { if (mFragmentManager.isStateSaved()) { Log.i(TAG, "Ignoring navigate() call: FragmentManager has already"
" saved its state"); return null; } String className = destination.getClassName(); if (className.charAt(0) == '.') { className = mContext.getPackageName() + className; } final Fragment frag = instantiateFragment(mContext, mFragmentManager, className, args); frag.setArguments(args); final FragmentTransaction ft = mFragmentManager.beginTransaction();
// ft.setPrimaryNavigationFragment(frag);
// if (mBackStack.size() > 1) { // // If the Fragment to be replaced is on the FragmentManager's // // back stack, a simple replace() isn't enough so we // // remove it from the back stack and put our replacement // // on the back stack in its place // mFragmentManager.popBackStack( // generateBackStackName(mBackStack.size(), mBackStack.peekLast()), // FragmentManager.POP_BACK_STACK_INCLUSIVE); // ft.addToBackStack(generateBackStackName(mBackStack.size(), destId)); // } isAdded = false; } else { ft.addToBackStack(generateBackStackName(mBackStack.size() + 1, destId)); isAdded = true; } if (navigatorExtras instanceof Extras && !isSingleTopReplacement) { Extras extras = (Extras) navigatorExtras; for (Map.Entry<View, String> sharedElement : extras.getSharedElements().entrySet()) { ft.addSharedElement(sharedElement.getKey(), sharedElement.getValue()); } } ft.setReorderingAllowed(true); ft.commit(); // The commit succeeded, update our view of the world if (isAdded) { mBackStack.add(destId); return destination; } else { return null; } }