Compose Material3 Adaptive Navigation Suite の 1.0.0-alpha01 が 2023/11/15 にリリースされたので、まだ alpha ではあるもののどのようなものか使ってみたメモのようなものになります。
使い方
以下のライブラリの依存を追加します。
androidx.compose.material3:material3-adaptive-navigation-suite:1.0.0-alpha01
NavigationSuiteScaffold
を使って Navigation で使用するアイテムの実装を行います。
@Composable
fun SampleApp() {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
val routes = remember { RootDestination.entries.map { it.route } }
NavigationSuiteScaffold(
navigationSuiteItems = {
RootDestination.entries.forEach { destination ->
val selected = currentRoute == destination.route
item(
icon = { Icon(...) },
label = { Text(...) },
selected = selected,
onClick = { ... }
)
}
}
) {
// Screen content
}
}
基本はこれだけで NavigationBar ↔︎ NavigationRail が自動で切り替わるようになります。
デフォルトでは以下のようなパターンで切り替わるようになっており、デフォルトには NavigationDrawer のパターンはありません。
画面の状態 | Type |
---|---|
フォルダブルで TableTop モードもしくは Phone 横向きなどの HeightSizeClass == Compactの時 | NavigationBar |
WidthSizeClass >= Medium | NavigationRail |
それ以外 | NavigationBar |
※ちなみにここでの NavigationDrawer はハンバーガーメニューがない、Expanded な状態の NavigationDrawer を指しています。
以下のような見た目になります。
NavigationBar | |
NavigationRail | |
NavigationDrawer |
カスタマイズ
画面サイズごとに使用する Navigation の種類を変更したい
NavigationSuiteScaffold
の引数にある NavigationSuiteType
で使用する Navigation の種類を変更することができます。
例えば WidthSizeClass == Expanded の時に NavigationDrawer を使いたい場合は以下のようにして NavigationSuiteType
を変えることで変更することが可能です。
val adaptiveInfo = currentWindowAdaptiveInfo()
val customNavSuiteType = if (windowSizeClass.widthSizeClass >= Expanded) {
NavigationSuiteType.NavigationDrawer
} else {
NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
}
NavigationSuiteScaffold(
layoutType = customNavSuiteType
) { ... }
Navigation のアイテムをカスタマイズしたい
NavigationBarItem
や NavigationRailItem
のカスタムと同じ API の範囲であればラベルの常に表示や色などはカスタマイズ可能です。
色に関しては NavigationSuiteScaffold
の引数から手軽にまとめて変更可能です。
fun item(
selected: Boolean,
onClick: () -> Unit,
icon: @Composable () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: @Composable (() -> Unit)? = null,
alwaysShowLabel: Boolean = true,
badge: (@Composable () -> Unit)? = null,
colors: NavigationSuiteItemColors? = null,
interactionSource: MutableInteractionSource = MutableInteractionSource()
)
※ NavigationBarItem
や NavigationRailItem
の標準の API でカスタムできること以上のことはできない
特定の条件で NavigationSuite を隠したい
NavigationSuiteScaffold
ではなくて NavigationSuiteScaffoldLayout
と NavigationSuite
を自分で組み合わせることで NavigationSuite
を隠す処理を実装できます。
(NavigationSuiteScaffold
の内部実装は NavigationSuiteScaffoldLayout
と NavigationSuite
を組み合わせたものになっている)
例えば MultibackStack を使わない、遷移した先で NavigationSuite
を非表示にしたい場合は以下のようなコードで非表示にすることが可能です。
@Composable
fun SampleApp() {
...
val navSuiteType = NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(currentWindowAdaptiveInfo())
NavigationSuiteScaffoldLayout(
layoutType = navSuiteType,
navigationSuite = {
if (isRootScreen) {
NavigationSuite(
layoutType = navSuiteType
) {
RootDestination.entries.forEach { destination ->
item( ... )
}
}
}
}
) {
Surface(
color = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground
) {
// Screen content
}
}
}
Compose Material3 Adaptive Navigation Suite は NavigationBar ↔︎ NavigationRail ↔︎ NavigationDrawer を少ない実装で切り替えてくれるライブラリになっています。
これまでだと Navigation のアイテムがそれぞれ別の Composable fun になっていて、共通のコードに落とし込むことが面倒だった部分が改善されていたり、大画面かどうかのロジックがライブラリで提供されるようになり、大画面対応がこれまで以上に対応しやすくなりそうですね。