簡體   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