Jetpack Compose:自定义 TextField 设计

新手上路,请多包涵

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

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

自定义文本输入

人们会认为简单地包装 BaseTextField 就可以了。但是,似乎 BaseTextField 组件中存在错误,我已经 打开了一个问题。这个错误将不允许用户在焦点离开文本字段后再次聚焦文本字段,直到组件被重新渲染。

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

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

原文由 foxtrotuniform6969 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

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

自定义 TextField 打印屏幕在这里

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

原文由 Thiago Souza 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 TextField

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

最后使用 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()
    )

在此处输入图像描述

原文由 Gabriele Mariotti 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题