Bar*_*tos 4 android android-jetpack android-jetpack-compose
是否可以使用 Compose 框架创建 Spinner?因为我正在尝试,但看起来没有像创建 Button 这样的 compose 方法:
Button(onClick = {},
modifier = Modifier
.align(Alignment.CenterHorizontally)
.fillMaxWidth()
)
{
Text(text = "Next")
}
Run Code Online (Sandbox Code Playgroud)
任何建议如何创建 Spinner ?我需要使用 xml 吗?
下面是如何在 Compose 中创建 Spinner/ComboBox/Select 的示例。 https://gist.github.com/chethu/f078658ef88d138ea92ab773c7396b5d
根据上面提到要点的答案,我想在一个可组合项中提出一个类似的解决方案,但接受对象而不是列表。在示例中,我仅使用了可以被任何对象替换的 Pair<String, String>。
package at.techbee.jtx.ui.compose.elements
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Composable
fun SampleSpinner(
list: List<Pair<String, String>>,
preselected: Pair<String, String>,
onSelectionChanged: (selection: Pair<String, String>) -> Unit
) {
var selected by remember { mutableStateOf(preselected) }
var expanded by remember { mutableStateOf(false) } // initial value
Box {
Column {
OutlinedTextField(
value = (selected.second),
onValueChange = { },
label = { Text(text = "My List") },
modifier = Modifier.fillMaxWidth(),
trailingIcon = { Icon(Icons.Outlined.ArrowDropDown, null) },
readOnly = true
)
DropdownMenu(
modifier = Modifier.fillMaxWidth(),
expanded = expanded,
onDismissRequest = { expanded = false },
) {
list.forEach { entry ->
DropdownMenuItem(
modifier = Modifier.fillMaxWidth(),
onClick = {
selected = entry
expanded = false
},
text = {
Text(
text = (entry.second),
modifier = Modifier.wrapContentWidth().align(Alignment.Start))
}
)
}
}
}
Spacer(
modifier = Modifier
.matchParentSize()
.background(Color.Transparent)
.padding(10.dp)
.clickable(
onClick = { expanded = !expanded }
)
)
}
}
@Preview(showBackground = true)
@Composable
fun SampleSpinner_Preview() {
MaterialTheme {
val entry1 = Pair("Key1", "Entry1")
val entry2 = Pair("Key2", "Entry2")
val entry3 = Pair("Key3", "Entry3")
SampleSpinner(
listOf(entry1, entry2, entry3),
preselected = entry2,
onSelectionChanged = { selected -> /* do something with selected */ }
)
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
////// 编辑 /////
我一直在尝试这个,现在我正在使用一个我更喜欢的解决方案。当您想在元素上放置修饰符时,先前解决方案中的间隔覆盖(也如之前答案中所建议的那样)并不是很好。因此,我在此解决方案中使用的是卡片,而不是 OutlinedTextField:
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SpinnerSample(
list: List<MyData>,
preselected: MyData,
onSelectionChanged: (myData: MyData) -> Unit,
modifier: Modifier = Modifier
) {
var selected by remember { mutableStateOf(preselected) }
var expanded by remember { mutableStateOf(false) } // initial value
OutlinedCard(
modifier = modifier.clickable {
expanded = !expanded
}
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.Top,
) {
Text(
text = selected.name,
modifier = Modifier.weight(1f)
.padding(horizontal = 16.dp, vertical = 8.dp)
)
Icon(Icons.Outlined.ArrowDropDown, null, modifier = Modifier.padding(8.dp))
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.fillMaxWidth() // delete this modifier and use .wrapContentWidth() if you would like to wrap the dropdown menu around the content
) {
list.forEach { listEntry ->
DropdownMenuItem(
onClick = {
selected = listEntry
expanded = false
onSelectionChanged(selected)
},
text = {
Text(
text = listEntry.name,
modifier = Modifier
//.wrapContentWidth() //optional instad of fillMaxWidth
.fillMaxWidth()
.align(Alignment.Start)
)
},
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun SpinnerSample_Preview() {
MaterialTheme {
val myData = listOf(MyData(0, "Apples"), MyData(1, "Bananas"), MyData(2, "Kiwis"))
SpinnerSample(
myData,
preselected = myData.first(),
onSelectionChanged = { },
modifier = Modifier.fillMaxWidth()
)
}
}
data class MyData (
val id: Int,
val name: String
)
Run Code Online (Sandbox Code Playgroud)
但是,使用 OutlinedTextField 的解决方案作为自动完成文本字段可能仍然很有趣。
| 归档时间: |
|
| 查看次数: |
1823 次 |
| 最近记录: |