web-dev-qa-db-ja.com

Androidの別のフラグメントに移動した後、ナビゲーションスタックをクリアする方法

私はAndroidで新しいNavigation Architecture Componentを使用しており、ナビゲーションスタックをクリアすることにこだわっています。新しいフラグメントに移動した後。

例: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);
50
Youssef El Behi

最初に、属性app:popUpTo='your_nav_graph_id'およびapp:popUpToInclusive="true"をアクションタグに追加します。

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

詳細については、 docs を参照してください。

NOTE:メソッドnavigate(@IdRes int resId)を使用してナビゲートすると、目的の結果が得られません。そのため、メソッドnavigate(@NonNull NavDirections directions)を使用しました。

73
Subhojit Shaw

注:明確なタスクは非推奨、公式の説明は

このメソッドは非推奨です。 setPopUpTo(int、boolean)をNavControllerのグラフのIDで使用し、包括的をtrueに設定します。

古い回答

コード内のすべてのファズを使いたくない場合は、アクションのプロパティでClear TaskLaunch Optionsをチェックするだけです。

Launch Options

編集:Android St​​udio 3.2 Beta 5の時点で、[タスクのクリア]は[起動オプション]ウィンドウに表示されなくなりましたが、引き続き使用できますナビゲーションのXMLコードのactionタグで、追加して

app:clearTask="true"
11
Mel

新しいナビゲーションアーキテクチャコンポーネントを使用して一部のフラグメントのナビゲーションでUPを無効にする方法

NavOptionとして.setClearTask(true)を指定する必要がありました。

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

                    }

                }
            });
4
Youssef El Behi

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

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

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

3
Nour Ahmed

あなたの質問は、Pop Behavior/Pop To/app:popUpTo(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"/>

OR

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

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

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

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
ROHIT LIEN