227

Android で新しいナビゲーション アーキテクチャ コンポーネントを使用していますが、新しいフラグメントに移動した後、ナビゲーション スタックをクリアするのに苦労しています。

例: 私は loginFragment にいて、ユーザーが戻るボタンを押したときに loginFragment に戻らないように、ホーム フラグメントに移動するときにこのフラグメントをスタックからクリアしたいと考えています。

単純なNavHostFragment.findNavController(Fragment).navigate(R.id.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());
                    }
                }
            });

navigate()で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);
4

14 に答える 14

75

あなたの質問は、Pop Behavior / Pop To / app:popUpTo (in xml) の使用方法に特に関連していると思います

ドキュメントでは、
ナビゲートする前に特定の目的地にポップアップします。これにより、この宛先が見つかるまで、一致しないすべての宛先がバック スタックからポップされます。

例 (シンプルな就活アプリ)
私のstart_screen_navグラフは次のようになります。

startScreenFragment (start) -> loginFragment -> EmployerMainFragment

                            -> loginFragment -> JobSeekerMainFragment

ナビゲートしてすべてをEmployerMainFragmentポップしたい場合、コードは次のようになります。 startScreenFragment

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"
            app:popUpToInclusive="true" />

移動して除外するEmployerMainFragmentすべてをポップしたい場合、コードは次のようになります。 startScreenFragment

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>

EmployerMainFragmentナビゲートしてポップしたいloginFragmentがそうしない startScreenFragment場合、コードは次のようになります。

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/loginFragment"
            app:popUpToInclusive="true"/>

また

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>
于 2019-07-01T07:39:40.613 に答える
61

私の場合、新しいフラグメントを開く前にバックスタックのすべてを削除する必要があったため、このコードを使用しました

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

最初の行は、私の場合は指定されたフラグメントに到達するまでバック スタックを削除します。これはホーム フラグメントなので、すべてのバック スタックを完全に削除し、ユーザーが fragment_company でクリックして戻ると、アプリを閉じます。

于 2019-07-27T22:33:31.473 に答える
4

次のように、ベース アクティビティのバック プレスをオーバーライドできます。

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

}
于 2019-09-04T06:12:50.220 に答える