3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Compose Material3 Adaptive Navigation Suite を使ってみる

Posted at

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 のアイテムをカスタマイズしたい

NavigationBarItemNavigationRailItem のカスタムと同じ 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()
)

NavigationBarItemNavigationRailItem の標準の API でカスタムできること以上のことはできない

特定の条件で NavigationSuite を隠したい

NavigationSuiteScaffold ではなくて NavigationSuiteScaffoldLayoutNavigationSuite を自分で組み合わせることで NavigationSuite を隠す処理を実装できます。 
(NavigationSuiteScaffold の内部実装は NavigationSuiteScaffoldLayoutNavigationSuite を組み合わせたものになっている)

例えば 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 になっていて、共通のコードに落とし込むことが面倒だった部分が改善されていたり、大画面かどうかのロジックがライブラリで提供されるようになり、大画面対応がこれまで以上に対応しやすくなりそうですね。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?