kotlin 从公开的下拉菜单组合,jetpack组合中选择选项时,不会触发文本字段的onValueChange

ulydmbyx  于 2022-11-16  发布在  Kotlin
关注(0)|答案(2)|浏览(98)

我正在尝试实现一个公开的下拉组合,我可以在我的android jetpack组合应用的多个部分中使用它。每当我从dropdownMenu中选择一个项目时,selectedOption就会在组合中设置,并分配给显示正确项目的文本字段值。但是,显示结果的文本字段的onValueChange事件没有被触发。这导致状态在我的应用的viewmodel层中没有被更新。遵循我的可组合代码。

// 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事件触发显示selectedOption的Textfield的onValueChange事件。

2nbm6dog

2nbm6dog1#

您只需在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)
        }
      }
    }
  }
}
chhqkbe1

chhqkbe12#

您可以像这样提升选中的选项状态,

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))
    },
)

并将PlantExposedSelect中的selectedOption替换为optionSelected

完整代码供参考

@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)
                }
            }
        }
    }
}

相关问题