Я использую новый компонент навигации архитектура в Android, и я застрял на то, чтобы очистить стек навигации после переезда в новый фрагмент.
Пример: Я в loginFragment и я хочу, чтобы этот фрагмент должен быть очищен от стека, когда я перейти на домашнюю фрагмент, так что пользователь не будет возвращен обратно в loginFragment, когда он нажимает кнопку "Назад".
Я использую простой NavHostFragment.findNavController(фрагмент).перейдите(ИД Р..homeFragment) для навигации.
Текущий Код :
mAuth.signInWithCredential(credential)
.addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
}
});
Я попытался с помощью NavOptions в перейдите(), но кнопки "назад" до сих пор отправляет меня обратно в loginFragment
NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setPopUpTo(R.id.homeFragment, false).build();
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment, null, navOptions);
Во-первых, добавить приложение атрибутов:popUpTo='your_nav_graph_id' " и " приложение:popUpToInclusive=то"Правда"` в действие тега.
<fragment
android:id="@+id/signInFragment"
android:name="com.glee.incog2.android.fragment.SignInFragment"
android:label="fragment_sign_in"
tools:layout="@layout/fragment_sign_in" >
<action
android:id="@+id/action_signInFragment_to_usersFragment"
app:destination="@id/usersFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
Во-вторых, перейдите к пункту назначения, используя выше действий в качестве параметра.
findNavController(fragment).navigate(
SignInFragmentDirections.actionSignInFragmentToUserNameFragment())
В разделе ["Документы"] (https://developer.android.com/guide/navigation/navigation-navigate#pop) для получения дополнительной информации.
Примечание: Если вы ориентируетесь используя метод навигации(@IdRes инт-л), вы выиграли'т получить желаемый результат. Следовательно, я использовал метод навигации (направления@ненулевое NavDirections)
.
Примечание: четкое задание устарела, официальному описанию
этот метод является устаревшим. Использовать setPopUpTo(тип int, boolean) с идентификатором NavController'ы график и набор к True.
Ответ
Если вы Don'т хочу пройти через все, что пуха в коде, вы можете просто проверить задача
в Параметры запуска
в свойствах действия.
Редактировать: как из Android студия версии 3.2 beta 5, четких задач не видна в окне Параметры запуска, но вы все еще можете использовать его в навигации'с XML-код, в действие тег, добавив
app:clearTask="true"
В моем случае мне нужно удалить все в резервную стопку, прежде чем я открываю новый фрагмент, так что я использовал этот код
navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);
первая строка удаляет резервную стопку, пока не достигает фрагмент, указанный в моем случае это'с хоум фрагмент поэтому он's снимает все обратно стек полностью , и когда пользователь нажимает кнопку Назад в fragment_company он закрывает приложение.
Я думаю, что ваш вопрос относится конкретно о том, как использовать поп поведения / поп / приложения:popUpTo (в XML)
В документации,<БР> <и>всплывающие для данного назначения перед переходом. Это соз все несовпадающие направления от задней стеке, пока это место не найдено.</я и GT;
Пример (простой поиск работы приложение)<БР> мой <б>start_screen_nav</б> график такой:<БР><БР> `` startScreenFragment (начало) -> loginFragment -> EmployerMainFragment
-> loginFragment -> JobSeekerMainFragment
если я хочу, чтобы перейти к `EmployerMainFragment и поп все <б>в том числе</б> `startScreenFragment` то <действий> код будет:
<действий
андроид:идентификатор=с"@+id и/action_loginFragment_to_employermainfragment и"
приложение:пункт назначения=то"@ИД/employerMainFragment и"
приложение:popUpTo=с"@+id и/startScreenFragment и" приложение:popUpToInclusive=на"Правда и" /> ``
если я хочу, чтобы перейти к EmployerMainFragment и поп все <б>кроме</б>
startScreenFragment` то <действий> код будет:
``
<действий
андроид:идентификатор=с"@+id и/action_loginFragment_to_employermainfragment и"
приложение:пункт назначения=то"@ИД/employerMainFragment и"
приложение:popUpTo=и" и quot+идентификатор/startScreenFragment&@;/> ``
если я хочу, чтобы перейти к EmployerMainFragment
поп loginFragment
но <б>нет</б> startScreenFragment
то <действий> код будет:
``
<действий
андроид:идентификатор=с"@+id и/action_loginFragment_to_employermainfragment и"
приложение:пункт назначения=то"@ИД/employerMainFragment и"
приложение:popUpTo=с"@+id и/loginFragment и"
приложение:popUpToInclusive=на"Правда и"/>
<б>или</б>
<действий
андроид:идентификатор=с"@+id и/action_loginFragment_to_employermainfragment и"
приложение:пункт назначения=то"@ИД/employerMainFragment и"
приложение:popUpTo=и" и quot+идентификатор/startScreenFragment&@;/> ``
Я, наконец, выяснить это спасибо https://stackoverflow.com/questions/50336112/how-to-disable-up-in-navigation-for-some-fragment-with-the-new-navigation-archit
Мне пришлось указать .setClearTask(правда) как NavOption.
mAuth.signInWithCredential(credential)
.addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setClearTask(true).build();
NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment,null,navOptions);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
}
});
NavController navController
=Navigation.findNavController(requireActivity(),
R.id.nav_host_fragment);// initialize navcontroller
if (navController.getCurrentDestination().getId() ==
R.id.my_current_frag) //for avoid crash
{
NavDirections action =
DailyInfoSelectorFragmentDirections.actionGoToDestionationFragment();
//for clear current fragment from stack
NavOptions options = new
NavOptions.Builder().setPopUpTo(R.id.my_current_frag, true).build();
navController.navigate(action, options);
}
Вы можете переопределить отжатый базовой активности, как это :
override fun onBackPressed() {
val navigationController = nav_host_fragment.findNavController()
if (navigationController.currentDestination?.id == R.id.firstFragment) {
finish()
} else if (navigationController.currentDestination?.id == R.id.secondFragment) {
// do nothing
} else {
super.onBackPressed()
}
}
Вот как я это сделал.
//here the R.id refer to the fragment one wants to pop back once pressed back from the newly navigated fragment
val navOption = NavOptions.Builder().setPopUpTo(R.id.startScorecardFragment, false).build()
//now how to navigate to new fragment
Navigation.findNavController(this, R.id.my_nav_host_fragment)
.navigate(R.id.instoredBestPractice, null, navOption)