![](/img/trans.png)
[英]Access TextField value from another composable function in Jetpack Compose
[英]onValueChange of textfield is not triggered when selecting an option from exposed dropdownMenu composable, jetpack compose
我正在尝试实现一个可组合的暴露下拉列表,我可以在我的 android jetpack compose 应用程序的多个部分中使用它。 每当我 select 来自 dropdownMenu 的项目时, selectedOption 都会在可组合项中设置并分配给显示正确项目的文本字段值。 但是,不会触发显示结果的 Textfield 的 onValueChange 事件。 这会导致 state 未在我的应用程序的视图模型层中更新。 遵循我的可组合代码。
// ExposedDropdownComposable.kt
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun PlantExposedSelect(
options: List<String>,
optionSelected: String,
label: String,
onOptionSelected: (String) -> Unit,
onFocusChange: (FocusState) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
var selectedOption by remember { mutableStateOf(optionSelected) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
readOnly = true,
value = selectedOption,
onValueChange = onOptionSelected
label = { Text(label) },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(
expanded = expanded
)
},
colors = ExposedDropdownMenuDefaults.textFieldColors(),
modifier = Modifier
.fillMaxWidth()
.onFocusChanged {
onFocusChange(it)
},
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
options.forEach { selectOption ->
DropdownMenuItem(
onClick = {
selectedOption = selectOption
expanded = false
Log.e("selectEdoption", selectedOption)
}
) {
Text(text = selectOption)
}
}
}
}
}
这是我在 AddPlantsScreen 中使用可组合的代码
PlantExposedSelect(
options = options,
optionSelected = lightState.text,
label = lightState.hint,
onOptionSelected = {
Log.e("eventValue", it)
viewModel.onEvent(AddEditPlantEvent.EnteredLight(it))
},
onFocusChange = {
viewModel.onEvent(AddEditPlantEvent.ChangedLightFocus(it))
},
)
如何使dropdownItem的onClick事件,触发Textfield的onValueChange事件显示selectedOption。
您可以像这样提升选定的选项 state,
val (optionSelected, setOptionSelected)= remember {
mutableStateOf("")
}
PlantExposedSelect(
options = options,
optionSelected = optionSelected,
label = "Label",
onOptionSelected = {
Log.e("eventValue", it)
setOptionSelected(it)
// viewModel.onEvent(AddEditPlantEvent.EnteredLight(it))
},
onFocusChange = {
// viewModel.onEvent(AddEditPlantEvent.ChangedLightFocus(it))
},
)
并将optionSelected
中的selectedOption
替换为PlantExposedSelect
。
完整代码供参考
@Composable
fun PlantExposedSelectSample() {
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4")
val (optionSelected, setOptionSelected)= remember {
mutableStateOf("")
}
PlantExposedSelect(
options = options,
optionSelected = optionSelected,
label = "Label",
onOptionSelected = {
Log.e("eventValue", it)
setOptionSelected(it)
// viewModel.onEvent(AddEditPlantEvent.EnteredLight(it))
},
onFocusChange = {
// viewModel.onEvent(AddEditPlantEvent.ChangedLightFocus(it))
},
)
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun PlantExposedSelect(
options: List<String>,
optionSelected: String,
label: String,
onOptionSelected: (String) -> Unit,
onFocusChange: (FocusState) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
readOnly = true,
value = optionSelected,
onValueChange = onOptionSelected,
label = {
Text(label)
},
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(
expanded = expanded
)
},
colors = ExposedDropdownMenuDefaults.textFieldColors(),
modifier = Modifier
.fillMaxWidth()
.onFocusChanged {
onFocusChange(it)
},
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
options.forEach { selectOption ->
DropdownMenuItem(
onClick = {
onOptionSelected(selectOption)
expanded = false
Log.e("selectEdoption", selectOption)
}
) {
Text(text = selectOption)
}
}
}
}
}
您可以简单地调用DropdownMenuItem
的onClick
参数中的onOptionSelected
而不是使用onValueChange
。
就像是:
@Composable
fun PlantExposedSelect(
//...
onOptionSelected: (String) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
var selectedOption by remember { mutableStateOf(optionSelected) }
ExposedDropdownMenuBox(
//....
) {
TextField(
value = selectedOption,
onValueChange = {}, //remove the function
//...
)
ExposedDropdownMenu(
/** ... **/
}
) {
options.forEach { selectOption ->
DropdownMenuItem(
onClick = {
selectedOption = selectOption
expanded = false
onOptionSelected //update your viewmodel here
}
) {
Text(text = selectOption)
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.