Skip to content

Commit 68fef6e

Browse files
authored
Basic menu examples (#371)
* basic menu examples * Make DropdownMenuWithDetails toggle expanded on click * Apply Spotless * Remove unneeded dependencies * Remove unneeded imports --------- Co-authored-by: jakeroseman <[email protected]>
1 parent 0c9024b commit 68fef6e

File tree

3 files changed

+218
-1
lines changed

3 files changed

+218
-1
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import com.example.compose.snippets.components.DatePickerExamples
4141
import com.example.compose.snippets.components.DialogExamples
4242
import com.example.compose.snippets.components.DividerExamples
4343
import com.example.compose.snippets.components.FloatingActionButtonExamples
44+
import com.example.compose.snippets.components.MenusExamples
4445
import com.example.compose.snippets.components.PartialBottomSheet
4546
import com.example.compose.snippets.components.ProgressIndicatorExamples
4647
import com.example.compose.snippets.components.ScaffoldExample
@@ -111,6 +112,7 @@ class SnippetsActivity : ComponentActivity() {
111112
TopComponentsDestination.TimePickerExamples -> TimePickerExamples()
112113
TopComponentsDestination.DatePickerExamples -> DatePickerExamples()
113114
TopComponentsDestination.CarouselExamples -> CarouselExamples()
115+
TopComponentsDestination.MenusExample -> MenusExamples()
114116
}
115117
}
116118
}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.compose.snippets.components
18+
19+
import androidx.compose.foundation.layout.Box
20+
import androidx.compose.foundation.layout.Column
21+
import androidx.compose.foundation.layout.fillMaxSize
22+
import androidx.compose.foundation.layout.fillMaxWidth
23+
import androidx.compose.foundation.layout.padding
24+
import androidx.compose.material.icons.Icons
25+
import androidx.compose.material.icons.automirrored.outlined.Help
26+
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
27+
import androidx.compose.material.icons.automirrored.outlined.Send
28+
import androidx.compose.material.icons.filled.MoreVert
29+
import androidx.compose.material.icons.outlined.Feedback
30+
import androidx.compose.material.icons.outlined.Info
31+
import androidx.compose.material.icons.outlined.Person
32+
import androidx.compose.material.icons.outlined.Settings
33+
import androidx.compose.material3.Button
34+
import androidx.compose.material3.DropdownMenu
35+
import androidx.compose.material3.DropdownMenuItem
36+
import androidx.compose.material3.FloatingActionButton
37+
import androidx.compose.material3.HorizontalDivider
38+
import androidx.compose.material3.Icon
39+
import androidx.compose.material3.IconButton
40+
import androidx.compose.material3.Text
41+
import androidx.compose.runtime.Composable
42+
import androidx.compose.runtime.getValue
43+
import androidx.compose.runtime.mutableStateOf
44+
import androidx.compose.runtime.remember
45+
import androidx.compose.runtime.setValue
46+
import androidx.compose.ui.Alignment
47+
import androidx.compose.ui.Modifier
48+
import androidx.compose.ui.tooling.preview.Preview
49+
import androidx.compose.ui.unit.dp
50+
51+
@Composable
52+
fun MenusExamples() {
53+
var currentExample by remember { mutableStateOf<(@Composable () -> Unit)?>(null) }
54+
55+
Box(modifier = Modifier.fillMaxSize()) {
56+
currentExample?.let {
57+
it()
58+
FloatingActionButton(
59+
onClick = { currentExample = null },
60+
modifier = Modifier
61+
.align(Alignment.BottomEnd)
62+
.padding(16.dp)
63+
) {
64+
Text(text = "Close example", modifier = Modifier.padding(16.dp))
65+
}
66+
return
67+
}
68+
69+
Column(modifier = Modifier.padding(16.dp)) {
70+
Button(onClick = { currentExample = { MinimalDropdownMenu() } }) {
71+
Text("Minimal dropdown menu")
72+
}
73+
Button(onClick = { currentExample = { LongBasicDropdownMenu() } }) {
74+
Text("Dropdown menu with many items")
75+
}
76+
Button(onClick = { currentExample = { DropdownMenuWithDetails() } }) {
77+
Text("Dropdown menu with sections and icons")
78+
}
79+
}
80+
}
81+
}
82+
83+
// [START android_compose_components_minimaldropdownmenu]
84+
@Composable
85+
fun MinimalDropdownMenu() {
86+
var expanded by remember { mutableStateOf(false) }
87+
Box(
88+
modifier = Modifier
89+
.padding(16.dp)
90+
) {
91+
IconButton(onClick = { expanded = !expanded }) {
92+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
93+
}
94+
DropdownMenu(
95+
expanded = expanded,
96+
onDismissRequest = { expanded = false }
97+
) {
98+
DropdownMenuItem(
99+
text = { Text("Option 1") },
100+
onClick = { /* Do something... */ }
101+
)
102+
DropdownMenuItem(
103+
text = { Text("Option 2") },
104+
onClick = { /* Do something... */ }
105+
)
106+
}
107+
}
108+
}
109+
// [END android_compose_components_minimaldropdownmenu]
110+
111+
@Preview
112+
@Composable
113+
fun MinimalDropdownMenuPreview() {
114+
MinimalDropdownMenu()
115+
}
116+
117+
// [START android_compose_components_longbasicdropdownmenu]
118+
@Composable
119+
fun LongBasicDropdownMenu() {
120+
var expanded by remember { mutableStateOf(false) }
121+
// Placeholder list of 100 strings for demonstration
122+
val menuItemData = List(100) { "Option ${it + 1}" }
123+
124+
Box(
125+
modifier = Modifier
126+
.padding(16.dp)
127+
) {
128+
IconButton(onClick = { expanded = !expanded }) {
129+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
130+
}
131+
DropdownMenu(
132+
expanded = expanded,
133+
onDismissRequest = { expanded = false }
134+
) {
135+
menuItemData.forEach { option ->
136+
DropdownMenuItem(
137+
text = { Text(option) },
138+
onClick = { /* Do something... */ }
139+
)
140+
}
141+
}
142+
}
143+
}
144+
// [END android_compose_components_longbasicdropdownmenu]
145+
146+
@Preview
147+
@Composable
148+
fun LongBasicDropdownMenuPreview() {
149+
LongBasicDropdownMenu()
150+
}
151+
152+
// [START android_compose_components_dropdownmenuwithdetails]
153+
@Composable
154+
fun DropdownMenuWithDetails() {
155+
var expanded by remember { mutableStateOf(false) }
156+
157+
Box(
158+
modifier = Modifier
159+
.fillMaxWidth()
160+
.padding(16.dp)
161+
) {
162+
IconButton(onClick = { expanded = !expanded }) {
163+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
164+
}
165+
DropdownMenu(
166+
expanded = expanded,
167+
onDismissRequest = { expanded = false }
168+
) {
169+
// First section
170+
DropdownMenuItem(
171+
text = { Text("Profile") },
172+
leadingIcon = { Icon(Icons.Outlined.Person, contentDescription = null) },
173+
onClick = { /* Do something... */ }
174+
)
175+
DropdownMenuItem(
176+
text = { Text("Settings") },
177+
leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
178+
onClick = { /* Do something... */ }
179+
)
180+
181+
HorizontalDivider()
182+
183+
// Second section
184+
DropdownMenuItem(
185+
text = { Text("Send Feedback") },
186+
leadingIcon = { Icon(Icons.Outlined.Feedback, contentDescription = null) },
187+
trailingIcon = { Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null) },
188+
onClick = { /* Do something... */ }
189+
)
190+
191+
HorizontalDivider()
192+
193+
// Third section
194+
DropdownMenuItem(
195+
text = { Text("About") },
196+
leadingIcon = { Icon(Icons.Outlined.Info, contentDescription = null) },
197+
onClick = { /* Do something... */ }
198+
)
199+
DropdownMenuItem(
200+
text = { Text("Help") },
201+
leadingIcon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
202+
trailingIcon = { Icon(Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) },
203+
onClick = { /* Do something... */ }
204+
)
205+
}
206+
}
207+
}
208+
// [END android_compose_components_dropdownmenuwithdetails]
209+
210+
@Preview
211+
@Composable
212+
fun DropdownMenuWithDetailsPreview() {
213+
DropdownMenuWithDetails()
214+
}

compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ enum class TopComponentsDestination(val route: String, val title: String) {
4444
PartialBottomSheet("partialBottomSheets", "Partial Bottom Sheet"),
4545
TimePickerExamples("timePickerExamples", "Time Pickers"),
4646
DatePickerExamples("datePickerExamples", "Date Pickers"),
47-
CarouselExamples("carouselExamples", "Carousel")
47+
CarouselExamples("carouselExamples", "Carousel"),
48+
MenusExample("menusExamples", "Menus")
4849
}

0 commit comments

Comments
 (0)