Как очистить стек навигации после перехода на другой фрагмент в Android

Я использую новый компонент навигации архитектура в 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);
Комментарии к вопросу (8)
Решение

Во-первых, добавить приложение атрибутов:popUpTo='your_nav_graph_id' " и " приложение:popUpToInclusive=то"Правда"` в действие тега.



Во-вторых, перейдите к пункту назначения, используя выше действий в качестве параметра.

findNavController(fragment).navigate(
     SignInFragmentDirections.actionSignInFragmentToUserNameFragment())

В разделе ["Документы"] (https://developer.android.com/guide/navigation/navigation-navigate#pop) для получения дополнительной информации.

Примечание: Если вы ориентируетесь используя метод навигации(@IdRes инт-л), вы выиграли&#39;т получить желаемый результат. Следовательно, я использовал метод навигации (направления@ненулевое NavDirections).

Комментарии (11)

Примечание: четкое задание устарела, официальному описанию

этот метод является устаревшим. Использовать setPopUpTo(тип int, boolean) с идентификатором NavController'ы график и набор к True.

Ответ

Если вы Don'т хочу пройти через все, что пуха в коде, вы можете просто проверить задача в Параметры запуска в свойствах действия.

Редактировать: как из Android студия версии 3.2 beta 5, четких задач не видна в окне Параметры запуска, но вы все еще можете использовать его в навигации'с XML-код, в действие тег, добавив

app:clearTask="true"
Комментарии (7)

В моем случае мне нужно удалить все в резервную стопку, прежде чем я открываю новый фрагмент, так что я использовал этот код

navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);

первая строка удаляет резервную стопку, пока не достигает фрагмент, указанный в моем случае это'с хоум фрагмент поэтому он's снимает все обратно стек полностью , и когда пользователь нажимает кнопку Назад в fragment_company он закрывает приложение.

Комментарии (0)

Я думаю, что ваш вопрос относится конкретно о том, как использовать поп поведения / поп / приложения: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&@;/> ``

Комментарии (1)

Я, наконец, выяснить это спасибо 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() {
                @Override
                public void onComplete(@NonNull Task 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());

                    }

                }
            });
Комментарии (7)
    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);
    }
Комментарии (0)

Вы можете переопределить отжатый базовой активности, как это :

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()
  }

}
Комментарии (0)

Вот как я это сделал.

 //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)
Комментарии (0)