From e4e4decf31c6e0143bbc57102443fac5397a7ca4 Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 09:44:35 +0100 Subject: [PATCH 1/6] Basic drop down menu examples --- .../compose/snippets/SnippetsActivity.kt | 2 + .../compose/snippets/components/Menu.kt | 153 ++++++++++++++++++ .../snippets/navigation/Destination.kt | 3 +- 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt b/compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt index 357cf556f..7bca1eaa2 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt @@ -41,6 +41,7 @@ import com.example.compose.snippets.components.DatePickerExamples import com.example.compose.snippets.components.DialogExamples import com.example.compose.snippets.components.DividerExamples import com.example.compose.snippets.components.FloatingActionButtonExamples +import com.example.compose.snippets.components.MenusExamples import com.example.compose.snippets.components.PartialBottomSheet import com.example.compose.snippets.components.ProgressIndicatorExamples import com.example.compose.snippets.components.ScaffoldExample @@ -111,6 +112,7 @@ class SnippetsActivity : ComponentActivity() { TopComponentsDestination.TimePickerExamples -> TimePickerExamples() TopComponentsDestination.DatePickerExamples -> DatePickerExamples() TopComponentsDestination.CarouselExamples -> CarouselExamples() + TopComponentsDestination.MenusExamples -> MenusExamples() } } } diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt new file mode 100644 index 000000000..0f9bbadc5 --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -0,0 +1,153 @@ +package com.example.compose.snippets.components + +import android.util.Log +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowDropDown +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Phone +import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MenuAnchorType +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.VerticalDivider +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun MenusExamples() { + var currentExample by remember { mutableStateOf<(@Composable () -> Unit)?>(null) } + + // Display the current example and the button to close it. + Box(modifier = Modifier.fillMaxSize()) { + currentExample?.let{ + it() + FloatingActionButton( + onClick = { currentExample = null }, + modifier = Modifier + .align(Alignment.BottomEnd) + .padding(16.dp) + ) { + Text(text = "Close example", modifier = Modifier.padding(16.dp)) + } + return + } + } + + // Display the list of available examples. + Column(modifier = Modifier.padding(16.dp)) { + Button(onClick = { currentExample = { BasicDropdownMenu() } }) { + Text("Action Bar Menu") + } + Button(onClick = { currentExample = { TextFieldDropdownMenu() } }) { + Text("Options Menu") + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +// [START android_compose_components_basicdropdownmenu] +@Composable +fun BasicDropdownMenu() { + var shouldDisplayMenu by remember { mutableStateOf(false) } + + TopAppBar( + title = { Text(text = "Basic menu example") }, + actions = { + IconButton(onClick = { shouldDisplayMenu = !shouldDisplayMenu }) { + Icon(Icons.Default.MoreVert, "") + } + DropdownMenu(expanded = shouldDisplayMenu, onDismissRequest = { shouldDisplayMenu = false }) { + DropdownMenuItem(text = { Text("Refresh") }, onClick = { /* Handle refresh! */ }) + DropdownMenuItem(text = { Text("Settings") }, onClick = { /* Handle settings! */ }) + } + } + ) +} +// [END android_compose_components_basicdropdownmenu] + +@Preview +@Composable +private fun BasicDropdownMenuPreview() { + BasicDropdownMenu() +} + +// [START android_compose_components_textfielddropdownmenu] +@Composable +fun TextFieldDropdownMenu() { + var expanded by remember { mutableStateOf(false) } + var selectedText by remember { mutableStateOf("") } + val options = listOf("Option 1", "Option 2", "Option 3") + + Box (modifier = Modifier.fillMaxWidth()) { + TextField( + value = selectedText, + onValueChange = { selectedText = it }, + modifier = Modifier.fillMaxWidth(), + label = { Text("Select an option") }, + trailingIcon = { + IconButton(onClick = { expanded = true }) { + Icon(Icons.Filled.ArrowDropDown, "Dropdown arrow") + } + }, + readOnly = true + ) + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + modifier = Modifier.fillMaxWidth() + ) { + options.forEach { option -> + DropdownMenuItem( + text = { Text(option) }, + onClick = { + selectedText = option + expanded = false + } + ) + } + } + } +} +// [END android_compose_components_textfielddropdownmenu] + +@Preview +@Composable +private fun TextFieldMenuPreview() { + TextFieldDropdownMenu() +} diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt index 20753d365..b99b8371d 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt @@ -44,5 +44,6 @@ enum class TopComponentsDestination(val route: String, val title: String) { PartialBottomSheet("partialBottomSheets", "Partial Bottom Sheet"), TimePickerExamples("timePickerExamples", "Time Pickers"), DatePickerExamples("datePickerExamples", "Date Pickers"), - CarouselExamples("carouselExamples", "Carousel") + CarouselExamples("carouselExamples", "Carousel"), + MenusExamples("menusExamples", "Menus") } From f1ad34c60df149e10c02a3a67efb2da68ae1c556 Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 09:01:33 +0000 Subject: [PATCH 2/6] Apply Spotless --- .../compose/snippets/components/Menu.kt | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt index 0f9bbadc5..c1a4aaf11 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -1,53 +1,48 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.compose.snippets.components -import android.util.Log -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.filled.Phone import androidx.compose.material3.Button import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExposedDropdownMenuBox -import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.FloatingActionButton -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MenuAnchorType -import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TopAppBar -import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp @Composable fun MenusExamples() { @@ -55,7 +50,7 @@ fun MenusExamples() { // Display the current example and the button to close it. Box(modifier = Modifier.fillMaxSize()) { - currentExample?.let{ + currentExample?.let { it() FloatingActionButton( onClick = { currentExample = null }, @@ -114,7 +109,7 @@ fun TextFieldDropdownMenu() { var selectedText by remember { mutableStateOf("") } val options = listOf("Option 1", "Option 2", "Option 3") - Box (modifier = Modifier.fillMaxWidth()) { + Box(modifier = Modifier.fillMaxWidth()) { TextField( value = selectedText, onValueChange = { selectedText = it }, From 2663794b1cabbb70b6921652e3f8a5cfc9331ba7 Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 10:07:51 +0100 Subject: [PATCH 3/6] Very minor formatting changes that spotless didn't do itself --- .../com/example/compose/snippets/components/Menu.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt index c1a4aaf11..4eaa00909 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -88,8 +88,14 @@ fun BasicDropdownMenu() { Icon(Icons.Default.MoreVert, "") } DropdownMenu(expanded = shouldDisplayMenu, onDismissRequest = { shouldDisplayMenu = false }) { - DropdownMenuItem(text = { Text("Refresh") }, onClick = { /* Handle refresh! */ }) - DropdownMenuItem(text = { Text("Settings") }, onClick = { /* Handle settings! */ }) + DropdownMenuItem( + text = { Text("Refresh") }, + onClick = { /* Handle refresh! */ } + ) + DropdownMenuItem( + text = { Text("Settings") }, + onClick = { /* Handle settings! */ } + ) } } ) From f165a614fd634f34aa27f666c2721463fe80b4e1 Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 10:13:10 +0100 Subject: [PATCH 4/6] Add missing content description --- .../main/java/com/example/compose/snippets/components/Menu.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt index 4eaa00909..8650f9283 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -85,7 +85,7 @@ fun BasicDropdownMenu() { title = { Text(text = "Basic menu example") }, actions = { IconButton(onClick = { shouldDisplayMenu = !shouldDisplayMenu }) { - Icon(Icons.Default.MoreVert, "") + Icon(Icons.Default.MoreVert, "Overflow menu button") } DropdownMenu(expanded = shouldDisplayMenu, onDismissRequest = { shouldDisplayMenu = false }) { DropdownMenuItem( From a4b47ca8c5ba2af43a6076b863550557569c7e3a Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 10:24:33 +0100 Subject: [PATCH 5/6] More very minor formatting changes that spotless didn't do itself --- .../java/com/example/compose/snippets/components/Menu.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt index 8650f9283..daf5cfa99 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -87,7 +87,10 @@ fun BasicDropdownMenu() { IconButton(onClick = { shouldDisplayMenu = !shouldDisplayMenu }) { Icon(Icons.Default.MoreVert, "Overflow menu button") } - DropdownMenu(expanded = shouldDisplayMenu, onDismissRequest = { shouldDisplayMenu = false }) { + DropdownMenu( + expanded = shouldDisplayMenu, + onDismissRequest = { shouldDisplayMenu = false }) + { DropdownMenuItem( text = { Text("Refresh") }, onClick = { /* Handle refresh! */ } From 246e68babcbe810f216624ffa972bfce24ae441c Mon Sep 17 00:00:00 2001 From: jakeroseman Date: Wed, 9 Oct 2024 09:26:55 +0000 Subject: [PATCH 6/6] Apply Spotless --- .../main/java/com/example/compose/snippets/components/Menu.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt index daf5cfa99..c28aaf929 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/components/Menu.kt @@ -89,8 +89,8 @@ fun BasicDropdownMenu() { } DropdownMenu( expanded = shouldDisplayMenu, - onDismissRequest = { shouldDisplayMenu = false }) - { + onDismissRequest = { shouldDisplayMenu = false } + ) { DropdownMenuItem( text = { Text("Refresh") }, onClick = { /* Handle refresh! */ }