繁体   English   中英

从暴露的 dropdownMenu 可组合、jetpack 组合中选择选项时,不会触发文本字段的 onValueChange

[英]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)
                }
            }
        }
    }
}

您可以简单地调用DropdownMenuItemonClick参数中的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM