序文
不可抗力の要因により、APP にアクティビティが 1 つしか持てず、他のページが断片的に表示される場合、この時点でルーティングにナビゲーションを使用すると非常に便利です。ただし、すべてのページのバックスタックを管理する必要があります。
以前、ナビゲーションの簡単な使い方について、比較的表面的な記事を書きましたが、今回はナビゲーションについてさらに深く感じたので記録しておきます。
必要
これまでのフラグメントの追加と削除の操作では、FragmentManager のトランザクションを使用して操作していました。
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container,new YourFragment())
.addToBackStack(null)
.commit();
公式のナビゲーション ドキュメントを見ると、通常のジャンプに <action> ID を使用することに加えて、目的地に直接ジャンプしたり、ジャンプ時にいくつかのナビゲーション オプション (navOptions) を追加したりすることもできることがわかります。
例: 宛先の mainPageFragment に直接ジャンプします。
NavHostFragment nav = (NavHostFragment)
getSupportFragmentManager().findFragmentById(R.id.page_host);
NavController navController = nav.getNavController();
navController.navigate(R.id.mainPageFragment);
ただし、ジャンプ先を直接指定しても、アクションを使用してジャンプしても、ジャンプ先のパスはバックスタックに追加されます。
例えば、ABCAの順番からAに戻った後、「戻る」をクリックして順番にCBAのページに戻ってくるのですが、CAにいるときにCに戻らなかったらどうしようかと考えます。 ?
解決
nav.xml ファイルで、popUpTo を CA の <action> に追加し、popUpToInclusive を true に設定します。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.metajoy.mynavigationdemo2.FragmentA"
android:label="FragmentA" >
<action
android:id="@+id/action_fragmentA_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.metajoy.mynavigationdemo2.FragmentB"
android:label="FragmentB" >
<action
android:id="@+id/action_fragmentB_to_fragmentC"
app:destination="@id/fragmentC" />
</fragment>
<fragment
android:id="@+id/fragmentC"
android:name="com.metajoy.mynavigationdemo2.FragmentC"
android:label="FragmentC" >
<action
android:id="@+id/action_fragmentC_to_fragmentA"
app:destination="@id/fragmentA"
app:popUpTo="@id/fragmentA"
app:popUpToInclusive="true"
/>
</fragment>
</navigation>
コード方法:
NavOptions navOptions = new NavOptions.Builder()
.setPopUpTo(R.id.fragmentA,true)
.build();
view.findViewById(R.id.c_bt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
navTo(R.id.action_fragmentC_to_fragmentA,navOptions);
//navTo(R.id.action_fragmentC_to_fragmentA);
}
});
このようにして、ABCA が実現され、A は戻るボタンをクリックして APP 操作を直接終了します。