![](/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.