ナビゲーション ドロワー

ナビゲーション ドロワー コンポーネントは、ユーザーがアプリのさまざまなセクションに移動できるスライドイン メニューです。ユーザーは、サイドからスワイプするか、メニュー アイコンをタップして有効にできます。

ナビゲーション ドロワーを実装する際の 3 つのユースケースを以下に示します。

  • コンテンツの整理: ニュース アプリやブログアプリなどで、ユーザーがさまざまなカテゴリを切り替えられるようにします。
  • アカウント管理: ユーザー アカウントがあるアプリで、アカウント設定とプロフィール セクションへのクイック リンクを提供します。
  • 機能の検出: 複雑なアプリでユーザーが機能を見つけてアクセスしやすくするため、複数の機能と設定を 1 つのメニューにまとめます。

マテリアル デザインには、次の 2 種類のナビゲーション ドロワーがあります。

  • 標準: 画面内のスペースを他のコンテンツと共有します。
  • モーダル: 画面内の他のコンテンツの上に表示されます。
ライトモードとダークモードのマテリアル デザイン 3 ナビゲーション ドロワーの例。
図 1. ナビゲーション ドロワーの例。

ModalNavigationDrawer コンポーザブルを使用して、ナビゲーション ドロワーを実装できます。

次の例のように、drawerContent スロットを使用して ModalDrawerSheet を指定し、ドロワーのコンテンツを指定します。

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    // Screen content
}

ModalNavigationDrawer は他にさまざまなドロワー パラメータを受け入れます。たとえば、次の例のように gesturesEnabled パラメータで、ドロワーがドラッグに応答するかどうかを切り替えることができます。

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            // Drawer contents
        }
    },
    gesturesEnabled = false
) {
    // Screen content
}

制御動作

ドロワーの開閉方法を制御するには、DrawerState を使用します。drawerState パラメータを使用して、DrawerStateModalNavigationDrawer に渡す必要があります。

DrawerState は、現在のドロワーの状態に関連するプロパティだけでなく、open 関数と close 関数へのアクセスを提供します。これらの suspend 関数は CoroutineScope を必要とします。これは rememberCoroutineScope を使用してインスタンス化できます。UI イベントに応じて一時停止関数を呼び出すこともできます。

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet { /* Drawer content */ }
    },
) {
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("Show drawer") },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    scope.launch {
                        drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                }
            )
        }
    ) { contentPadding ->
        // Screen content
    }
}

ナビゲーション ドロワー内にグループを作成する

次のスニペットは、セクションと区切り線を含む詳細なナビゲーション ドロワーを作成する方法を示しています。

@Composable
fun DetailedDrawerExample(
    content: @Composable (PaddingValues) -> Unit
) {
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    ModalNavigationDrawer(
        drawerContent = {
            ModalDrawerSheet {
                Column(
                    modifier = Modifier.padding(horizontal = 16.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Spacer(Modifier.height(12.dp))
                    Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
                    HorizontalDivider()

                    Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Item 1") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Item 2") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )

                    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))

                    Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Settings") },
                        selected = false,
                        icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                        badge = { Text("20") }, // Placeholder
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Help and feedback") },
                        selected = false,
                        icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                        onClick = { /* Handle click */ },
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        },
        drawerState = drawerState
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text("Navigation Drawer Example") },
                    navigationIcon = {
                        IconButton(onClick = {
                            scope.launch {
                                if (drawerState.isClosed) {
                                    drawerState.open()
                                } else {
                                    drawerState.close()
                                }
                            }
                        }) {
                            Icon(Icons.Default.Menu, contentDescription = "Menu")
                        }
                    }
                )
            }
        ) { innerPadding ->
            content(innerPadding)
        }
    }
}

コードに関する主なポイント

  • セクション、区切り線、ナビゲーション項目を含む ColumndrawerContent に入力します。
  • ModalDrawerSheet は、ドロワーのマテリアル デザイン スタイリングを提供します。
  • HorizontalDivider は、ドロワー内のセクションを区切ります。
  • ModalNavigationDrawer はドロワーを作成します。
  • drawerContent は、ドロワーのコンテンツを定義します。
  • ModalDrawerSheet 内の Column は、ドロワー要素を垂直方向に配置します。
  • NavigationDrawerItem コンポーザブルは、ドロワー内の個々のアイテムを表します。
  • Scaffold は、TopAppBar を含む画面の基本構造を提供します。
  • TopAppBarnavigationIcon は、ドロワーの開閉状態を制御します。

結果

次の画像は、ドロワーを開いたときにセクションとアイテムが表示される様子を示しています。

2 つのセクションを含む詳細なナビゲーション ドロワー。各セクションには、ラベル付きの複数の項目とアイコンがあります。
図 2. 2 つのネストされたグループを含むナビゲーション ドロワーが開いている。

参考情報