Skip to content

Commit a59caf2

Browse files
committed
basic menu examples
1 parent 0c9024b commit a59caf2

File tree

5 files changed

+208
-1
lines changed

5 files changed

+208
-1
lines changed

compose/snippets/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ android {
7777

7878
dependencies {
7979
implementation(libs.androidx.work.runtime.ktx)
80+
implementation(libs.androidx.core)
8081
val composeBom = platform(libs.androidx.compose.bom)
8182
implementation(composeBom)
8283
androidTestImplementation(composeBom)

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: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package com.example.compose.snippets.components
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.material.icons.Icons
9+
import androidx.compose.material.icons.automirrored.filled.Help
10+
import androidx.compose.material.icons.automirrored.filled.OpenInNew
11+
import androidx.compose.material.icons.automirrored.filled.Send
12+
import androidx.compose.material.icons.automirrored.outlined.Help
13+
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
14+
import androidx.compose.material.icons.automirrored.outlined.Send
15+
import androidx.compose.material.icons.filled.Feedback
16+
import androidx.compose.material.icons.filled.Info
17+
import androidx.compose.material.icons.filled.MoreVert
18+
import androidx.compose.material.icons.filled.Person
19+
import androidx.compose.material.icons.filled.Settings
20+
import androidx.compose.material3.Button
21+
import androidx.compose.material3.DropdownMenu
22+
import androidx.compose.material3.DropdownMenuItem
23+
import androidx.compose.material3.FloatingActionButton
24+
import androidx.compose.material3.HorizontalDivider
25+
import androidx.compose.material3.Icon
26+
import androidx.compose.material3.IconButton
27+
import androidx.compose.material3.Text
28+
import androidx.compose.runtime.Composable
29+
import androidx.compose.runtime.getValue
30+
import androidx.compose.runtime.mutableStateOf
31+
import androidx.compose.runtime.remember
32+
import androidx.compose.runtime.setValue
33+
import androidx.compose.ui.Alignment
34+
import androidx.compose.ui.Modifier
35+
import androidx.compose.ui.tooling.preview.Preview
36+
import androidx.compose.ui.unit.dp
37+
38+
@Composable
39+
fun MenusExamples() {
40+
var currentExample by remember { mutableStateOf<(@Composable () -> Unit)?>(null) }
41+
42+
Box(modifier = Modifier.fillMaxSize()) {
43+
currentExample?.let {
44+
it()
45+
FloatingActionButton(
46+
onClick = { currentExample = null },
47+
modifier = Modifier
48+
.align(Alignment.BottomEnd)
49+
.padding(16.dp)
50+
) {
51+
Text(text = "Close example", modifier = Modifier.padding(16.dp))
52+
}
53+
return
54+
}
55+
56+
Column(modifier = Modifier.padding(16.dp)) {
57+
Button(onClick = { currentExample = { MinimalDropdownMenu() } }) {
58+
Text("Minimal dropdown menu")
59+
}
60+
Button(onClick = { currentExample = { LongBasicDropdownMenu() } }) {
61+
Text("Dropdown menu with many items")
62+
}
63+
Button(onClick = { currentExample = { DropdownMenuWithDetails() } }) {
64+
Text("Dropdown menu with sections and icons")
65+
}
66+
}
67+
}
68+
}
69+
70+
// [START android_compose_components_minimaldropdownmenu]
71+
@Composable
72+
fun MinimalDropdownMenu() {
73+
var expanded by remember { mutableStateOf(false) }
74+
Box(
75+
modifier = Modifier
76+
.padding(16.dp)
77+
) {
78+
IconButton(onClick = { expanded = !expanded }) {
79+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
80+
}
81+
DropdownMenu(
82+
expanded = expanded,
83+
onDismissRequest = { expanded = false }
84+
) {
85+
DropdownMenuItem(
86+
text = { Text("Option 1") },
87+
onClick = { /* Do something... */ }
88+
)
89+
DropdownMenuItem(
90+
text = { Text("Option 2") },
91+
onClick = { /* Do something... */ }
92+
)
93+
}
94+
}
95+
}
96+
// [END android_compose_components_minimaldropdownmenu]
97+
98+
@Preview
99+
@Composable
100+
fun MinimalDropdownMenuPreview() {
101+
MinimalDropdownMenu()
102+
}
103+
104+
// [START android_compose_components_longbasicdropdownmenu]
105+
@Composable
106+
fun LongBasicDropdownMenu() {
107+
var expanded by remember { mutableStateOf(false) }
108+
// Placeholder list of 100 strings for demonstration
109+
val menuItemData = List(100) { "Option ${it + 1}" }
110+
111+
Box(
112+
modifier = Modifier
113+
.padding(16.dp)
114+
) {
115+
IconButton(onClick = { expanded = !expanded }) {
116+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
117+
}
118+
DropdownMenu(
119+
expanded = expanded,
120+
onDismissRequest = { expanded = false }
121+
) {
122+
menuItemData.forEach { option ->
123+
DropdownMenuItem(
124+
text = { Text(option) },
125+
onClick = { /* Do something... */ }
126+
)
127+
}
128+
}
129+
}
130+
}
131+
// [END android_compose_components_longbasicdropdownmenu]
132+
133+
@Preview
134+
@Composable
135+
fun LongBasicDropdownMenuPreview() {
136+
LongBasicDropdownMenu()
137+
}
138+
139+
// [START android_compose_components_dropdownmenuwithdetails]
140+
@Composable
141+
fun DropdownMenuWithDetails() {
142+
var expanded by remember { mutableStateOf(false) }
143+
144+
Box(
145+
modifier = Modifier
146+
.fillMaxWidth()
147+
.padding(16.dp)
148+
) {
149+
IconButton(onClick = { expanded = true }) {
150+
Icon(Icons.Default.MoreVert, contentDescription = "More options")
151+
}
152+
DropdownMenu(
153+
expanded = expanded,
154+
onDismissRequest = { expanded = false }
155+
) {
156+
// First section
157+
DropdownMenuItem(
158+
text = { Text("Profile") },
159+
leadingIcon = { Icon(Icons.Default.Person, contentDescription = null) },
160+
onClick = { /* Do something... */ }
161+
)
162+
DropdownMenuItem(
163+
text = { Text("Settings") },
164+
leadingIcon = { Icon(Icons.Default.Settings, contentDescription = null) },
165+
onClick = { /* Do something... */ }
166+
)
167+
168+
HorizontalDivider()
169+
170+
// Second section
171+
DropdownMenuItem(
172+
text = { Text("Send Feedback") },
173+
leadingIcon = { Icon(Icons.Default.Feedback, contentDescription = null) },
174+
trailingIcon = { Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null) },
175+
onClick = { /* Do something... */ }
176+
)
177+
178+
HorizontalDivider()
179+
180+
// Third section
181+
DropdownMenuItem(
182+
text = { Text("About") },
183+
leadingIcon = { Icon(Icons.Default.Info, contentDescription = null) },
184+
onClick = { /* Do something... */ }
185+
)
186+
DropdownMenuItem(
187+
text = { Text("Help") },
188+
leadingIcon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
189+
trailingIcon = { Icon(Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) },
190+
onClick = { /* Do something... */ }
191+
)
192+
}
193+
}
194+
}
195+
// [END android_compose_components_dropdownmenuwithdetails]
196+
197+
@Preview
198+
@Composable
199+
fun DropdownMenuWithDetailsPreview() {
200+
DropdownMenuWithDetails()
201+
}

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
}

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ targetSdk = "34"
5050
version-catalog-update = "0.8.4"
5151
wearComposeFoundation = "1.4.0"
5252
wearComposeMaterial = "1.4.0"
53+
core = "1.13.0"
5354

5455
[libraries]
5556
accompanist-adaptive = { module = "com.google.accompanist:accompanist-adaptive", version.ref = "accompanist" }
@@ -127,6 +128,7 @@ kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutine
127128
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
128129
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
129130
play-services-wearable = { module = "com.google.android.gms:play-services-wearable", version.ref = "playServicesWearable" }
131+
androidx-core = { group = "androidx.core", name = "core", version.ref = "core" }
130132

131133
[plugins]
132134
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }

0 commit comments

Comments
 (0)