メニュー

プルダウン メニューを使用すると、ユーザーはアイコン、テキスト フィールド、その他のコンポーネントをクリックして、一時的なサーフェスに表示されたオプションのリストから選択できます。このガイドでは、基本的なメニューと、区切り線やアイコンを含むより複雑なメニューの両方を作成する方法について説明します。

2 つのオプションが表示されたプルダウン メニュー。縦に 3 つ並んだ点のアイコンは、クリックするとメニューが開くことを示します。
図 1. 2 つの項目がリストされた基本的なプルダウン メニュー。

API サーフェス

DropdownMenuDropdownMenuItemIconButton コンポーネントを使用して、カスタム プルダウン メニューを実装します。DropdownMenu コンポーネントと DropdownMenuItem コンポーネントはメニュー項目の表示に使用され、IconButton はプルダウン メニューの表示と非表示を切り替えるトリガーです。

DropdownMenu コンポーネントの主なパラメータは次のとおりです。

  • expanded: メニューが表示されているかどうかを示します。
  • onDismissRequest: メニューの終了を処理するために使用されます。
  • content: メニューのコンポーザブル コンテンツ。通常は DropdownMenuItem コンポーザブルが含まれます。

DropdownMenuItem の主なパラメータは次のとおりです。

  • text: メニュー項目に表示されるコンテンツを定義します。
  • onClick: メニュー内のアイテムとのインタラクションを処理するコールバック。

基本的なプルダウン メニューを作成する

次のスニペットは、最小限の DropdownMenu 実装を示しています。

@Composable
fun MinimalDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            DropdownMenuItem(
                text = { Text("Option 1") },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Option 2") },
                onClick = { /* Do something... */ }
            )
        }
    }
}

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

  • 2 つのメニュー項目を含む基本的な DropdownMenu を定義します。
  • expanded パラメータは、メニューの表示 / 非表示を制御します。
  • onDismissRequest パラメータは、ユーザーがメニューを閉じたときに実行されるコールバックを定義します。
  • コンポーザブル DropdownMenuItem は、プルダウン メニューで選択可能な項目を表します。
  • IconButton は、メニューの展開と折りたたみを切り替えます。

結果

縦に 3 つの点が並んだアイコンをクリックすると表示されるプルダウン メニュー。メニューに、[Option 1] と [Option 2] の 2 つの選択可能なオプションが表示されます。
図 2. オプションが 2 つしかない最小限のプルダウン メニュー。

長いプルダウン メニューを作成する

すべてのメニュー項目を一度に表示できない場合、DropdownMenu はデフォルトでスクロール可能になります。次のスニペットは、スクロール可能な長いプルダウン メニューを作成します。

@Composable
fun LongBasicDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    // Placeholder list of 100 strings for demonstration
    val menuItemData = List(100) { "Option ${it + 1}" }

    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            menuItemData.forEach { option ->
                DropdownMenuItem(
                    text = { Text(option) },
                    onClick = { /* Do something... */ }
                )
            }
        }
    }
}

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

  • コンテンツの合計の高さが使用可能なスペースを超えると、DropdownMenu はスクロール可能になります。このコードは、100 個のプレースホルダ アイテムを表示するスクロール可能な DropdownMenu を作成します。
  • forEach ループは DropdownMenuItem コンポーザブルを動的に生成します。アイテムは遅延作成されません。つまり、100 個のドロップダウン アイテムがすべて作成され、コンポジション内に存在します。
  • IconButton は、クリックされると DropdownMenu の開閉をトリガーします。
  • DropdownMenuItem 内の onClick ラムダを使用すると、ユーザーがメニュー項目を選択したときに実行されるアクションを定義できます。

結果

上記のコード スニペットは、次のスクロール可能なメニューを生成します。

多くのオプションを含むプルダウン メニュー。すべての項目を表示するにはスクロールが必要。
図 3. 長いスクロール可能なプルダウン メニュー。

区切り線を使用して長いプルダウン メニューを作成する

次のスニペットは、プルダウン メニューのより高度な実装を示しています。このスニペットでは、メニュー項目に先頭と末尾のアイコンが追加され、区切り線でメニュー項目のグループが区切られています。

@Composable
fun DropdownMenuWithDetails() {
    var expanded by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // First section
            DropdownMenuItem(
                text = { Text("Profile") },
                leadingIcon = { Icon(Icons.Outlined.Person, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Settings") },
                leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Second section
            DropdownMenuItem(
                text = { Text("Send Feedback") },
                leadingIcon = { Icon(Icons.Outlined.Feedback, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Third section
            DropdownMenuItem(
                text = { Text("About") },
                leadingIcon = { Icon(Icons.Outlined.Info, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Help") },
                leadingIcon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
        }
    }
}

このコードは、Box 内で DropdownMenu を定義します。

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

  • leadingIcon パラメータと trailingIcon パラメータは、DropdownMenuItem の先頭と末尾にアイコンを追加します。
  • IconButton はメニューの展開をトリガーします。
  • DropdownMenu には複数の DropdownMenuItem コンポーザブルが含まれており、それぞれが選択可能なアクションを表しています。
  • HorizontalDivider コンポーザブルは、メニュー項目のグループを区切る水平線を挿入します。

結果

上記のスニペットでは、アイコンと区切り線を含むプルダウン メニューが生成されます。

[プロフィール]、[設定]、[フィードバックを送信]、[概要]、[ヘルプ] のセクションを含むプルダウン メニュー。各オプションには、プロフィール用の人物アイコンなどのアイコンが表示されます。
図 4. 先頭と末尾のアイコンを含むセクションに分割されたプルダウン メニュー。

参考情報