【问题标题】:Jetpack Compose: Custom TextField designJetpack Compose:自定义 TextField 设计
【发布时间】:2020-10-26 18:07:45
【问题描述】:

一般来说,Jetpack Compose 中的大多数组件似乎都很容易定制。

但是,TextField 却不能这样说。例如,假设我想做这样的事情:

人们会认为简单地包装BaseTextField 就可以了。但是,BaseTextField 组件中似乎存在错误,而我有opened an issue。在重新渲染组件之前,此错误将不允许用户在焦点离开文本字段后再次关注文本字段。

引用这一点,我尝试自定义 OutlinedTextFieldTextField 组件,但无法自定义它们看起来像上图。如果不是因为光标颜色使用了activeColor 属性,我可以让它工作。

创建一个类似于上面的可用文本字段的正确解决方法是什么?

【问题讨论】:

  • 如何在 TextField 下方显示字符计数器?
  • @Thracian 好吧,您需要将所有内容包装在一个列中,以便计数器显示在文本字段下方,然后使用文本字段的状态获取“.length”
  • 非常感谢。我认为它是 TextField 的原生组件。我猜仍然没有字符计数器、辅助文本和错误消息。
  • 如何从 TextField 中删除下划线,我也无法删除它。我正在尝试为带有前导图标的 TopBar 搜索创建一个没有下划线的圆角 TextField。 BasicTextField 没有图标属性,所以我尝试用 TextField 来做,但如果它不起作用,我会用 BasicTextField 和 Image 手动做。
  • 你需要添加一个足够厚的边框来覆盖现有的线条

标签: android android-jetpack android-textinputlayout android-jetpack-compose


【解决方案1】:

您可以使用TextField:

  • 删除带有label = null 的标签
  • 使用TextFieldDefaults.textFieldColors 参数应用自定义颜色来隐藏指示器。
  • onValueChange 中添加一个函数来修复here 中描述的最大字符数

最后使用一个Column添加2个Text可组合来完成外部标签和计数器文本。

类似:

var text by remember { mutableStateOf("") }
val maxChar = 5

Column(){
    //External label
    Text(
        text = "Label",
        modifier = Modifier.fillMaxWidth(),
        textAlign = TextAlign.Start,
        color = Blue
    )

    TextField(
        value = text,
        onValueChange = {
            if (it.length <= maxChar) text = it
        },
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        shape = RoundedCornerShape(8.dp),
        trailingIcon = {
            Icon(Icons.Filled.Add, "", tint = Blue)
        },
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = ....,
            focusedIndicatorColor =  Color.Transparent, //hide the indicator
            unfocusedIndicatorColor = .....)
    )
    //counter message
    Text(
        text = "${text.length} / $maxChar",
        textAlign = TextAlign.End,
        color = Blue,
        style = MaterialTheme.typography.caption, //use the caption text style
        modifier = Modifier.fillMaxWidth()
    )

【讨论】:

    【解决方案2】:

    通过这个例子你可以学到很多东西。使用 1.0.0,您可以这样做:

    Column {
            var textState by remember { mutableStateOf("") }
            val maxLength = 110
            val lightBlue = Color(0xffd8e6ff)
            val blue = Color(0xff76a9ff)
            Text(
                text = "Caption",
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(bottom = 4.dp),
                textAlign = TextAlign.Start,
                color = blue
            )
            TextField(
                modifier = Modifier.fillMaxWidth(),
                value = textState,
                colors = TextFieldDefaults.textFieldColors(
                    backgroundColor = lightBlue,
                    cursorColor = Color.Black,
                    disabledLabelColor = lightBlue,
                    focusedIndicatorColor = Color.Transparent,
                    unfocusedIndicatorColor = Color.Transparent
                ),
                onValueChange = {
                    if (it.length <= maxLength) textState = it
                },
                shape = RoundedCornerShape(8.dp),
                singleLine = true,
                trailingIcon = {
                    if (textState.isNotEmpty()) {
                        IconButton(onClick = { textState = "" }) {
                            Icon(
                                imageVector = Icons.Outlined.Close,
                                contentDescription = null
                            )
                        }
                    }
                }
            )
            Text(
                text = "${textState.length} / $maxLength",
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = 4.dp),
                textAlign = TextAlign.End,
                color = blue
            )
        }
    

    【讨论】:

      【解决方案3】:

      好吧,在解决 issue I mentioned 之前,选择是:

      1. 回滚到 Compose 版本 1.0.0-alpha04(问题在 alpha05 中引入)
      2. TextFieldOutlinedTextField 添加边框,如下所示:
        TextField(
            value = myValue,
            onValueChange = myOnChange,
            modifier = Modifier.clip(myShape).border(5.dp, myColor)
        )
        

      【讨论】:

      • 在较新的版本中,您已将形状传递给 TextField 本身,因为它会用传入的形状覆盖剪辑参数
      猜你喜欢
      • 2021-11-14
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多