Jetpack Compose系列(7) - TextField

类似于View体系中的EditText,Compose中也提供了输入框:

· TextField

· OutlinedTextField

· BasicTextField

使用方式与其他组件一样,我们先看一个最简单的样式:

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    Column() {
        TextField(value = "输入内容...", onValueChange = {
            Log.i("textInputing","get the text : $it in TextField")
        })
        OutlinedTextField(value = "输入内容...", onValueChange = {
            Log.i("textInputing","get the text : $it in OutTextField")
        })
    }
}

对应的预览为:

image.gif
相信看到这里,你已经有了种感觉像EditText的感觉了。其实,TextField效果,跟View体系的EditText默认效果一致,而OutlinedTextField的效果则带有一个边框。

对比下二者的构造函数,不难发现异同点:


@Composable
fun TextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions(),
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape =
        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
)

TextField有两个构造函数,对比下差异不难发现就前面两个参数类型不同:

image.gif
对应的OutlinedTextField也有两个构造函数:

@Composable
fun OutlinedTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small,
    colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()
)

区别是三处参数类型不同:

image.gif
当然,特么的BasicTextField也有两个构造函数:

@Composable
fun BasicTextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    cursorBrush: Brush = SolidColor(Color.Black),
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
        @Composable { innerTextField -> innerTextField() }
)

对应的是两处参数类型不同:

image.gif
根据谷歌官方介绍:

1、TextField是Material Design实现,默认样式为填充;

2、OutlinedTextField是Material Design实现的轮毂样式版本;

3、BasicTextField,原生输入框,允许自定义高度,没有提供提示或占位符等装饰。相对业务场景较少。

其余参数解释如下:
· value: String :输入框显示的文本。

· value: TextFieldValue :输入框显示的文本,包含输入框编辑状态信息,相对于双向绑定。可以用来更新文本、光标,还可以从其他位置直接观察到这些值的变化等。

· onValueChange: (TextFieldValue) -> Unit :更新TextFieldValue中的值时的回调,回调参数为更新后的TextFieldValue;

· modifier: Modifier :修饰符。(之前文章中讲到过)

· textStyle: TextStyle :输入框样式,三种控件默认样式不同。

· label: () -> Unit = null :获得输入焦点,顶头的文字提示,接收一个组件的lamba表达式,内容一般为Text

· placeholder: () -> Unit)? = null :当输入框获得焦点的时候,要展示的占位符。

· leadingIcon: () -> Unit :输入框左边显示的内容,leadingIcon接收来自一个组件的lambda表达式(可以是图标、文本或者其他组件)。

· trailingIcon: () -> Unit :输入框右边显示的内容,trailingIcon接收来自一个组件的lambda表达式(可以是图标、文本或者其他组件)。

· isErrorValue: Boolean = false:输入框中的输入内容是否处于输入失败的状态,如果为true,则label,Icon等控件会展示相应的错误显示状态。

· visualTransformation: VisualTransformation = VisualTransformation.None :输入类型的视图变化。可以改变输入的字符串(例如官方推荐的PasswordVisualTransformation()可以将输入的字符串转换为……显示),默认情况下无视觉转换效果。

· keyboardOptions: KeyboardOptions :配置的软件键盘选项,例如KeyboardType和ImeAction。

· singleLine: Boolean :限制文本单行,类似于TextView的singleLine属性。

· maxLines: Int :见名知意,最大行数,当singleLine=true时,本属性自动变为1。

· onImeActionPerformed: 输入服务执行ImeAction时触发的回调。

· onTextInputStarted: (SoftwareKeyboardController) -> Unit {} :文本输入服务与软键盘建立连接时的回调,可用于请求显示或隐藏软件键盘。

· interactionState :暂不明。

· activeColor: Color = MaterialTheme.colors.primary:输入框获取到焦点时的状态,底部指示符和光标的颜色(遵从Material Design设计理念)。

· inactiveColor: Color = MaterialTheme.colors.onSurface :输入框不处于焦点时的标签、底部指示符的颜色(遵从Material Design设计理念)。

· errorColor: Color = MaterialTheme.colors.error :isErrorValue设置为true时使用的标签,底部指示器,光标的颜色。

· backgroundColor: Color = MaterialTheme.colors.onSurface.copy :输入框的背景色。

· shape: Shape = MaterialTheme.shapes.small.copy(bottomLeft = ZeroCornerSize, bottomRight = ZeroCornerSize) :用来描绘输入框的形状。

让我们看到最初的代码:

TextField(value = "输入内容...", onValueChange = {
    Log.i("textInputing","get the text : $it in TextField")
})
OutlinedTextField(value = "输入内容...", onValueChange = {
    Log.i("textInputing","get the text : $it in OutTextField")
})

这段代码运行后,你会发现,无论你怎么操作,文本框内容都不会更新文本,但是日志有打印。

1111.gif

image.gif
这里就需要value: String/TextFieldValue 参数了。这个参数会回调更新的内容。这点需要自行处理内容更新的特点,还是跟EditText不一样的。

@Composable
fun CustomView() {
    val textValue = remember { mutableStateOf("") }
    Column() {
        TextField(
            value = textValue.value,
            onValueChange = {
                textValue.value = it
            },
        )
        OutlinedTextField(value = textValue.value, onValueChange = {
            textValue.value = it
        })
    }
}

上述代码中,新建textValue变量来保存状态,textValue类型是MutableState,使用mutableStateOf(“”)生成实例,初始化空字符串包装到状态保持器中,用于在输入字段中存储和显示文本。remember关键字将状态包装到remember()中,Compose告诉编译程序应该通过重新编译来持久化该值的方式。如果这没使用remember(),每次更改状态时,都会丢失并设置为默认值,即 “”。

随后,将textValue持有者的值连接到TextField,并在onValueChange回调中更改状态持有者的内部值。这样就显示出输入框的显示文本为键盘中输入的文字了。

222.gif

这里接下来讲解一些重要的属性:

Label

即获得输入焦点,顶头的文字提示,接收一个组件的lambda表达式,一般传入Text。例如:

TextField(value = "", onValueChange = {},label = {Text("Label")})

对应的显示效果为:

image.gif

label.gif

leadingIcon trailingIcon

分别是输入框左边和右边的显示内容,接受来自一个组件的lamba表达式,可以是文本、图标或其他组件。例如如下代码:

val textValue = remember { mutableStateOf("") }
Column() {
    TextField(
        value = textValue.value,
        onValueChange = {
            textValue.value = it
        },
        leadingIcon = {
            androidx.compose.material.Icon(
                imageVector = Icons.Filled.CheckCircle,
                contentDescription = null
            )
        }
    )
    TextField(
        value = textValue.value,
        onValueChange = {
            textValue.value = it
        },
        trailingIcon = {
            androidx.compose.material.Icon(
                imageVector = Icons.Filled.Check,
                contentDescription = null
            )
        }
    )
}

对应的显示效果为:

image.gif
(注意这里调用的Icon函数,不理解的话可以看前两篇文章有详细讲到)

Color

Color使用方式较简单,直接在属性里声明即可,例如:

TextField(
    value = textValue.value,
    onValueChange = {
        textValue.value = it
    },
    leadingIcon = {
        androidx.compose.material.Icon(
            imageVector = Icons.Filled.CheckCircle,
            contentDescription = null
        )
    },
    colors = TextFieldDefaults.textFieldColors(
        textColor = Color(0xFFD30062),
        backgroundColor = Color.Transparent
    )
)

对应的显示效果为:

image.gif
除此之外,textFieldColors()函数还可以通过设置其他参数来设置其他很多颜色,具体参数如下:

@Composable
fun textFieldColors(
    // 输入的文字颜色
    textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current),

    // 禁用 TextField 时,已有的文字颜色
    disabledTextColor: Color = textColor.copy(ContentAlpha.disabled),

    // 输入框的背景颜色,当设置为 Color.Transparent 时,将透明
    backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = BackgroundOpacity),

    // 输入框的光标颜色
    cursorColor: Color = MaterialTheme.colors.primary,

    // 当 TextField 的 isError 参数为 true 时,光标的颜色
    errorCursorColor: Color = MaterialTheme.colors.error,

    // 当输入框处于焦点时,底部指示器的颜色
    focusedIndicatorColor: Color = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),

    // 当输入框不处于焦点时,底部指示器的颜色
    unfocusedIndicatorColor: Color = MaterialTheme.colors.onSurface.copy(alpha = UnfocusedIndicatorLineOpacity),

    // 禁用 TextField 时,底部指示器的颜色
    disabledIndicatorColor: Color = unfocusedIndicatorColor.copy(alpha = ContentAlpha.disabled),

    // 当 TextField 的 isError 参数为 true 时,底部指示器的颜色
    errorIndicatorColor: Color = MaterialTheme.colors.error,

    // TextField 输入框前头的颜色
    leadingIconColor: Color = MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),

    // 禁用 TextField 时 TextField 输入框前头的颜色
    disabledLeadingIconColor: Color = leadingIconColor.copy(alpha = ContentAlpha.disabled),

    // 当 TextField 的 isError 参数为 true 时 TextField 输入框前头的颜色
    errorLeadingIconColor: Color = leadingIconColor,

    // TextField 输入框尾部的颜色
    trailingIconColor: Color = MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),

    // 禁用 TextField 时 TextField 输入框尾部的颜色
    disabledTrailingIconColor: Color = trailingIconColor.copy(alpha = ContentAlpha.disabled),

    // 当 TextField 的 isError 参数为 true 时 TextField 输入框尾部的颜色
    errorTrailingIconColor: Color = MaterialTheme.colors.error,

    // 当输入框处于焦点时,Label 的颜色
    focusedLabelColor: Color = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),

    // 当输入框不处于焦点时,Label 的颜色
    unfocusedLabelColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),

    // 禁用 TextField 时,Label 的颜色
    disabledLabelColor: Color = unfocusedLabelColor.copy(ContentAlpha.disabled),

    // 当 TextField 的 isError 参数为 true 时,Label 的颜色
    errorLabelColor: Color = MaterialTheme.colors.error,

    // Placeholder 的颜色
    placeholderColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),

    // 禁用 TextField 时,placeholder 的颜色
    disabledPlaceholderColor: Color = placeholderColor.copy(ContentAlpha.disabled)
)

这里参数太多,不做赘述了。

GitHub 加速计划 / compose / compose
33.26 K
5.15 K
下载
compose - Docker Compose是一个用于定义和运行多容器Docker应用程序的工具,通过Compose文件格式简化应用部署过程。
最近提交(Master分支:1 个月前 )
16652ed2 Signed-off-by: Alexandr Hacicheant <a.hacicheant@gmail.com> 3 天前
c6a76b9b full diff: https://github.com/docker/buildx/compare/v0.17.0...v0.17.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl> 3 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐