公式ドキュメントはこちら。
基本的な使い方
Navigation
の導入時には NavigationUI
経由で NavController
を Toolbar
や Drawer
、 BottomNavigationView
を組み合わせるとことになります。
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/layout_toolbar" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:elevation="4dp" /> </com.google.android.material.appbar.AppBarLayout> <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:defaultNavHost="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/layout_toolbar" app:navGraph="@navigation/nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>
class RootActivity : AppCompatActivity { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_root) val toolbar = findViewById<Toolbar>(R.id.toolbar) val navController = findNavController(R.id.nav_host_fragment) toolbar.setupWithNavController(navController) } }
これで Toolbar
が nav_graph
に応じるようになります。
応用的な使い方
setupWithNavController
や setupActionBarWithNavController
の第2引数 AppBarConfiguration
に何も指定しなければ AppBarConfiguration(navController.graph)
が入ります。
この結果 navController
にセットされているナビゲーショングラフの startDestination
が AppBarConfiguration
の mTopLevelDestinations
に登録されます。
ref AppBarConfiguration.Builder /** * Create a new Builder whose only top level destination is the start destination * of the given {@link NavGraph}. The Up button will not be displayed when on the * start destination of the graph. * * @param navGraph The NavGraph whose start destination should be considered the only * top level destination. The Up button will not be displayed when on the * start destination of the graph. */ public Builder(@NonNull NavGraph navGraph) { mTopLevelDestinations.add(NavigationUI.findStartDestination(navGraph).getId()); }
mTopLevelDestinations
に登録されると、JavaDocの通りUp buttonが表示されなくなります。
ref AppBarConfiguration /** * The set of destinations by id considered at the top level of your information hierarchy. * The Up button will not be displayed when on these destinations. * * @return The set of top level destinations by id. */ @NonNull public Set<Integer> getTopLevelDestinations() { return mTopLevelDestinations; }
このため mTopLevelDestinations
に渡すidを調整することで、Up buttonを隠したり表示させたりすることができます。
If you want to customize which destinations are considered top-level destinations, you can instead pass a set of destination IDs to the constructor, as shown below:
ref Update UI components with NavigationUI | Android Developers
Up buttonを常に表示したい場合
idが含まれていないSetを用意します。
val appBarConfiguration = AppBarConfiguration.Builder(emptySet()).build()
findViewById<Toolbar>(R.id.toolbar).setupWithNavController(navController, appBarConfiguration)
この時 FallbackOnNavigateUpListener
が必要になっていないかご注意ください。
渡す場合には AppBarConfiguration.Builder(emptySet()).setFallbackOnNavigateUpListener("ココ").build()
とすることになります。
/** * Adds a {@link OnNavigateUpListener} that will be called as a fallback if the default * behavior of {@link androidx.navigation.NavController#navigateUp} * returns <code>false</code>. * * @param fallbackOnNavigateUpListener Listener that will be invoked if * {@link androidx.navigation.NavController#navigateUp} * returns <code>false</code>. * @return this {@link Builder} */ @NonNull public Builder setFallbackOnNavigateUpListener( @Nullable OnNavigateUpListener fallbackOnNavigateUpListener) { mFallbackOnNavigateUpListener = fallbackOnNavigateUpListener; return this; }
例えば onBackPressed
を追加することで、前のActivityに戻る処理なんかが考えられます。
Up buttonを常に非表示にしたい場合
ナビゲーショングラフの全てのidが含まれているSetを用意します。
NavController.iterator()
はイテレーターを返してくるので、minSDKVersionに合わせた実装になると思います。
val navController = findNavController(R.id.nav_host_fragment) val idSet = mutableSetOf<Int>() navController.graph.iterator().forEach { idSet.add(it.id) } findViewById<Toolbar>(R.id.toolbar) .setupWithNavController(navController, AppBarConfiguration.Builder(idSet).build())
終わりに
色々とカスタマイズしたいケース、するケースが出ることで公式ライブラリ側で色々と修正が入るのではないかなーと思っています。 Navigation 2.0では今回のような方法を取ることになりますが、バージョンが上がればまた違う方法が出るかなと。
Navigationを入れるとFragmentがとんでもなく使いやすくなるので、これからもっと理解を深めていきたいと思います!