私は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);
最初に、属性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)
を使用しました。
注:明確なタスクは非推奨、公式の説明は
このメソッドは非推奨です。 setPopUpTo(int、boolean)をNavControllerのグラフのIDで使用し、包括的をtrueに設定します。
古い回答
コード内のすべてのファズを使いたくない場合は、アクションのプロパティでClear Task
のLaunch Options
をチェックするだけです。
編集:Android Studio 3.2 Beta 5の時点で、[タスクのクリア]は[起動オプション]ウィンドウに表示されなくなりましたが、引き続き使用できますナビゲーションのXMLコードのactionタグで、追加して
app:clearTask="true"
新しいナビゲーションアーキテクチャコンポーネントを使用して一部のフラグメントのナビゲーションで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());
}
}
});
私の場合、新しいフラグメントを開く前にバックスタックのすべてを削除する必要があったため、このコードを使用しました
navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);
最初の行は、私の場合は指定されたホームフラグメントであるフラグメントに達するまでバックスタックを削除します。したがって、すべてのバックスタックを完全に削除し、ユーザーがfragment_companyで戻ってクリックすると、アプリを閉じます。
あなたの質問は、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"/>
次のように、ベースアクティビティのバックプレスをオーバーライドできます。
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()
}
}