ナビゲーションドロワー

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

ナビゲーション ドロワーの実装には、次の 3 つのユースケースを考えてみましょう。

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

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

  • 標準: 画面上のスペースを他のコンテンツと共有できます。
  • モーダル: 画面内の他のコンテンツの上に表示されます。

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

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

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            Divider()
            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 イベントに応じて suspend 関数を呼び出すこともできます。

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
    }
}