【问题标题】:dropdown list on button click compose按钮上的下拉列表单击撰写
【发布时间】:2021-11-29 00:12:31
【问题描述】:

如何在单击按钮时创建下拉菜单项。在 Jetpack compose 中?

喜欢这里,但按钮:

      DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            toggle = iconButton,
            dropdownOffset = Position(24.dp, 0.dp),
            toggleModifier = modifier
        ) {
            options.forEach {
                DropdownMenuItem(onClick = {}) {
                    Text(it)
                }
            }
        }

【问题讨论】:

  • 不知道你想要实现什么,但参数切换可以用于任何你想要的。因此,如果您想要一个常规按钮而不是图标按钮,只需将其替换为 toggle = {Button(onClick={setExpanded(!expanded)}){Text("Open Dropdown")}}。我希望这对你有所帮助。

标签: android android-jetpack-compose


【解决方案1】:

前面的答案是正确的,但是缺少关键部分。 DropdownMenu 和打开它的按钮 都应该包含在 Box 中。只有这样,打开按钮才会用作菜单的。 这是我的版本:

@Composable
fun DropdownMenu(
    colorSelected: Color = scColors.primary,
    colorBackground: Color = scColors.onSurface,
    expanded: Boolean,
    selectedIndex: Int,
    items: List<String>,
    onSelect: (Int) -> Unit,
    onDismissRequest: () -> Unit,
    content: @Composable () -> Unit
) {
    Box {
        content()
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = onDismissRequest,
            modifier = Modifier
                .height(300.dp)
                .fillMaxWidth()
                .background(
                    color = colorBackground,
                    shape = RoundedCornerShape(16.dp)
                )
        ) {
            items.forEachIndexed { index, s ->
                if (selectedIndex == index) {
                    DropdownMenuItem(
                        modifier = Modifier
                            .fillMaxWidth()
                            .background(
                                color = colorSelected,
                                shape = RoundedCornerShape(16.dp)
                            ),
                        onClick = { onSelect(index) }
                    ) {
                        Text(
                            text = s,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                            modifier = Modifier.fillMaxWidth()
                        )
                    }
                } else {
                    DropdownMenuItem(
                        modifier = Modifier.fillMaxWidth(),
                        onClick = { onSelect(index) }
                    ) {
                        Text(
                            text = s,
                            color = Color.DarkGray,
                            textAlign = TextAlign.Center,
                            modifier = Modifier.fillMaxWidth()
                        )
                    }
                }
            }
        }
    }
}

然后,DropdownMenu 接受打开锚按钮作为内容:

val items = listOf(
    "English",
    "Russian",
    "Spanish",
    "French",
    "German",
    "Hebrew"
)

@Preview
@Composable
fun TestDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }

    var selectedIndex by remember { mutableStateOf(0) }
    val buttonTitle = items[selectedIndex]
    DropdownMenu(
        colorSelected = scColors.onSurface,
        colorBackground = scColors.primary,
        expanded = expanded,
        selectedIndex = selectedIndex,
        items = items,
        onSelect = { index ->
            selectedIndex = index
            expanded = false
        },
        onDismissRequest = {
            expanded = false
        }) {

        Button(
            onClick = {
                expanded = true
            }
        ) {
            Text(
                text = buttonTitle,
                color = Color.Black,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    }
}

【讨论】:

    【解决方案2】:

    你可以使用类似的东西:

       var expanded by remember { mutableStateOf(false) }
    
       Button(onClick = { expanded = true }){
            Text ("...")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            //....
        ) {
            items.forEachIndexed { index, s ->
                //....
            }
        }
    

    【讨论】:

      【解决方案3】:

      你可以使用这个在compose中创建一个下拉列表

      list : 要显示的列表

      label : label 是在 textview 中显示的提示

      default : 在 textview 中设置默认值

      validateInput = 您可以通过在单击的按钮上将 validateInput 状态更改为 true 来验证输入并相应地处理它

      fun dropdownList(
      list: List<String>,
      label: String,
      defaultValue: String = "",
      validateInput: Boolean
      ): String {
      
      var expanded by remember { mutableStateOf(false) }
      var selectedText by remember { mutableStateOf(defaultValue) }
      var textFieldSize by remember { mutableStateOf(Size.Zero) }
      var isError by remember { mutableStateOf(false) }
      
      if (validateInput && selectedText.isEmpty())
          isError = true
      
      val icon = if (expanded)
          Icons.Filled.ArrowDropUp
      else
          Icons.Filled.ArrowDropDown
      
      
      Column(modifier = Modifier.padding(bottom = 2.dp, top = 2.dp)) {
          OutlinedTextField(
              value = selectedText,
              onValueChange = {
                  selectedText = it
              },
              modifier = Modifier
                  .fillMaxWidth()
                  .onGloballyPositioned { coordinates ->
                      textFieldSize = coordinates.size.toSize()
                  },
              label = { Text(label) },
              trailingIcon = {
                  Icon(icon, "contentDescription",
                      Modifier.clickable { expanded = !expanded })
              },
              isError = isError
          )
          DropdownMenu(
              expanded = expanded,
              onDismissRequest = { expanded = false },
              modifier = Modifier
                  .width(with(LocalDensity.current) { textFieldSize.width.toDp() })
          ) {
              list.forEach { label ->
                  DropdownMenuItem(onClick = {
                      selectedText = label
                      expanded = false
                  }) {
                      Text(text = label)
                  }
              }
          }
          if (isError) {
              Text(
                  text = "$label can't be empty",
                  color = Color.Red,
                  textAlign = TextAlign.End,
                  modifier = Modifier.fillMaxWidth()
              )
          }
      }
      return selectedText
      }
      

      Github gist 链接DropdownList.kt

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多