Используя Компонент Архитектуры Навигации, у нас также есть динамическая навигация от кода, подобного этому в некоторых случаях:
navController.navigate(R.id.cartFragment)
Затем, когда нам нужно перейти к новому корневому назначению (обратная навигация закроет приложение) из этогоdestination, у нас нет возможности узнать, каково наше текущее корневое назначение, поэтому мы не знаем, как установить назначение popUpTo.
val navigationOptions = NavOptions.Builder().setPopUpTo(R.id.???, true).build()
navController.navigate(R.id.loginFragment, null, navigationOptions)
Если мы установим его в пункт назначения, не находящийся в backstack, то получим журнал предупреждений (от popBackStackInternal
in NavController
):
"Игнорирование popBackStackк месту назначения *: id / splashFragment, поскольку он не был найден в текущем заднем стеке "
Случай происходит потому, что у нас также есть несколько случаев до этого в потоке, где мы устанавливаем PopUpTo так зависимым от потокау нас разные корневые пункты назначения.
Я рассмотрел все доступные методы на NavController
и попытался поразмышлять над mBackStack
, но не смог найти способ очистить backstack.
Как очистить backstack, не зная текущего корневого пункта назначения? Редактировать: добавлен пример навигационного графика
<fragment
android:id="@+id/navigation_cart"
android:name="ProjectsFragment_"
android:label="Cart"
tools:layout="@layout/fragment_cart" />
<fragment
android:id="@+id/loginFragment"
android:name="LoginFragment_"
android:label="Login"
tools:layout="@layout/fragment_login">
<--! Dynamic navigation to either Consent or Cart based on state -->
<action
android:id="@+id/action_login_to_home"
app:destination="@id/navigation_cart"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_loginFragment_to_consentFragment"
app:destination="@id/consentFragment" />
<action
android:id="@+id/action_loginFragment_to_contactFragment"
app:destination="@id/contactFragment" />
</fragment>
<fragment
android:id="@+id/splashFragment"
android:name="SplashFragment_"
android:label="SplashFragment"
tools:layout="@layout/fragment_splash">
<--! Dynamic navigation to either Onboarding, Login or Cart based on state -->
</fragment>
<dialog
android:id="@+id/consentFragment"
android:name="ConsentFragment"
android:label="ConsentFragment"
tools:layout="@layout/fragment_consent" />
<fragment
android:id="@+id/onboardingIntroFragment"
android:name="OnboardingIntroFragment_"
android:label="OnboardingIntroFragment"
tools:layout="@layout/fragment_onboarding">
<action
android:id="@+id/action_onboardingIntroFragment_to_loginFragment"
app:destination="@id/loginFragment"
app:popUpTo="@id/onboardingIntroFragment"
app:popUpToInclusive="true" />
</fragment>
<dialog
android:id="@+id/contactFragment"
android:name="ContactFragment"
android:label="ContactFragment"
tools:layout="@layout/fragment_contact" />
Что касается конкретных случаев выше из SplashFragment, мы будем динамически перемещаться либо к Onboarding, Login или Cart на основе состояния.Если после этого мы перейдем к «Входу», а после успешного входа перейдите к «Динамическому» к «Корзине».
В обоих случаях общей динамической навигации мы не знаем, какой у нас корневой адрес назначения, и хотя не можем правильно установить popUpTo.При вызове из Splash это SplashFragment, при вызове из Login это LoginFragment или другой случай при оформлении заказа это может быть CartFragment или другой фрагмент, который является корневым назначением.
Как определить динамически, что является корневым назначениемили просто очистить backstack как часть навигации?
Хотя это немного упрощено, так как в нашем приложении больше случаев того же шаблона.