跳转到内容

TextField

TextField 是 COUI 中的基础输入组件,用于接收用户的文本输入,视觉对齐 ColorOS COUIEditText。默认呈现 ColorOS 设置对话框中的输入形态:16sp 裸文本 + 细下划线,聚焦时主题色 1dp 线条从起始边展开,标签作为普通占位符使用。同时提供纯描边圆角矩形、完全无装饰(卡片内)两种形态,以及可选的浮动标签、错误抖动、字数统计、清除按钮与密码切换。

引入

kotlin
import io.github.suqi8.coui.kmp.basic.TextField
import io.github.suqi8.coui.kmp.basic.TextFieldMode

基本用法

TextField 组件可以用于获取用户输入:

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "用户名"
)

信息

此 TextField 组件现在也支持最新基于状态的版本,具体请参考 State-based 文档。

输入框类型

带标签输入框(占位符)

默认情况下(useLabelAsPlaceholder = true,对应 ColorOS 全部输入框使用的 HintDisable 样式),标签是普通占位符:输入框为空时显示,输入文本后消失:

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "邮箱地址"
)

浮动标签

设置 useLabelAsPlaceholder = false 可启用 COUI HintAnim 浮动标签:输入框获得焦点或有内容时,标签缩小到 10sp 并上浮(200ms,COUI move ease 曲线):

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "请输入内容",
    useLabelAsPlaceholder = false
)

组件状态

禁用状态

kotlin
var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = "禁用输入框",
    enabled = false
)

只读状态

kotlin
var text by remember { mutableStateOf("这是只读内容") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "只读输入框",
    readOnly = true
)

背景模式

TextField 通过 backgroundMode 支持 COUIEditText 的三种背景模式:

  • TextFieldMode.Line(默认):无填充;0.33dp 细下划线,聚焦时 1dp 主题色线条从起始边展开——即 ColorOS 设置的对话框 / 底部面板输入形态
  • TextFieldMode.Rectangle:纯描边圆角矩形(10dp 圆角,无填充);未聚焦 0.33dp 细描边,聚焦 1dp 主题色描边;默认文本加粗
  • TextFieldMode.None:无任何背景装饰——裸文本,即白卡输入使用的形态(见 InputView
kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "矩形样式",
    backgroundMode = TextFieldMode.Rectangle
)

无装饰(None)模式

TextFieldMode.None 移除所有背景装饰——当外层容器(例如白色输入卡片)已经提供视觉框架时使用:

kotlin
var text by remember { mutableStateOf("") }

Card {
    TextField(
        value = text,
        onValueChange = { text = it },
        label = "裸输入框",
        backgroundMode = TextFieldMode.None,
        modifier = Modifier.padding(horizontal = 16.dp)
    )
}

仅显示聚焦线

Line 模式下设置 justShowFocusLine = true 可隐藏静息下划线,只保留聚焦时展开的线条,对应 ColorOS 设置卡片内偏好输入(COUIInputPreference couiJustShowFocusLine,真机默认开启)。把输入框放进 Card 即为设置里的完整观感:

kotlin
var text by remember { mutableStateOf("") }

Card {
    TextField(
        value = text,
        onValueChange = { text = it },
        label = "设备名称",
        justShowFocusLine = true,
        modifier = Modifier.padding(horizontal = 16.dp)
    )
}

错误状态

设置 isError = true 会将描边 / 下划线与标签染成错误色,并播放一次水平抖动动画:

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "仅限数字",
    isError = text.isNotEmpty() && !text.all { it.isDigit() }
)

字数统计

设置 maxCount 会在输入框尾部显示「当前/上限」计数,并在超出上限时截断输入。达到上限后计数变红:

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "最多 10 个字符",
    maxCount = 10
)

清除按钮

设置 showClearButton = true 会在输入框聚焦且非空时显示清除(快速删除)按钮,点按后清空全部文本:

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "快速删除",
    showClearButton = true
)

密码可见切换

设置 showPasswordToggle = true 会显示一个眼睛按钮用于切换密码可见性。隐藏时文本以圆点掩码显示:

kotlin
var password by remember { mutableStateOf("") }

TextField(
    value = password,
    onValueChange = { password = it },
    label = "密码",
    showPasswordToggle = true,
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)

属性

TextField 属性

属性名类型说明默认值是否必须
valueString 或 TextFieldValue输入框的文本值-
onValueChange(String) -> Unit 或 (TextFieldValue) -> Unit文本变化时的回调函数-
modifierModifier应用于输入框的修饰符Modifier
backgroundModeTextFieldMode背景装饰模式TextFieldMode.Line
insideMarginDpSize输入框内部边距TextFieldDefaults.insideMargin(backgroundMode)
colorsTextFieldColors输入框使用的颜色TextFieldDefaults.textFieldColors()
cornerRadiusDp圆角半径(Rectangle 模式)TextFieldDefaults.CornerRadius
labelString标签 / 占位符文本""
useLabelAsPlaceholderBoolean普通占位符(true)或浮动标签(false)true
justShowFocusLineBooleanLine 模式:隐藏静息下划线false
enabledBoolean输入框是否可用true
readOnlyBoolean输入框是否只读false
isErrorBoolean错误状态(红色染色+抖动)false
maxCountInt?最大字符数;显示计数null
showClearButtonBoolean聚焦时显示清除按钮false
showPasswordToggleBoolean显示密码可见切换按钮false
textStyleTextStyle输入文本样式TextFieldDefaults.textStyle(backgroundMode)
keyboardOptionsKeyboardOptions键盘选项配置KeyboardOptions.Default
keyboardActionsKeyboardActions键盘操作配置KeyboardActions.Default
leadingIcon@Composable (() -> Unit)?前置图标null
trailingIcon@Composable (() -> Unit)?后置图标null
singleLineBoolean是否为单行输入false
maxLinesInt最大行数如果 singleLine 为 true 则为 1,否则为 Int.MAX_VALUE
minLinesInt最小行数1
visualTransformationVisualTransformation视觉转换器VisualTransformation.None
onTextLayout(TextLayoutResult) -> Unit文本布局变化回调{}
interactionSourceMutableInteractionSource?交互源null
cursorBrushBrush光标画刷SolidColor(colors.borderColor)

TextField(state-based)属性

属性名类型说明默认值是否必须
stateTextFieldState保存文本与选择的状态对象-
modifierModifier应用于输入框的修饰符Modifier
backgroundModeTextFieldMode背景装饰模式TextFieldMode.Line
insideMarginDpSize输入框内部边距TextFieldDefaults.insideMargin(backgroundMode)
colorsTextFieldColors输入框使用的颜色TextFieldDefaults.textFieldColors()
cornerRadiusDp圆角半径(Rectangle 模式)TextFieldDefaults.CornerRadius
labelString标签 / 占位符文本""
useLabelAsPlaceholderBoolean普通占位符(true)或浮动标签(false)true
justShowFocusLineBooleanLine 模式:隐藏静息下划线false
enabledBoolean输入框是否可用true
readOnlyBoolean输入框是否只读false
isErrorBoolean错误状态(红色染色+抖动)false
maxCountInt?最大字符数;显示计数null
showClearButtonBoolean聚焦时显示清除按钮false
showPasswordToggleBoolean显示密码可见切换按钮false
inputTransformationInputTransformation?输入变换器null
textStyleTextStyle输入文本样式TextFieldDefaults.textStyle(backgroundMode)
keyboardOptionsKeyboardOptions键盘选项配置KeyboardOptions.Default
onKeyboardActionKeyboardActionHandler?键盘动作处理器null
lineLimitsTextFieldLineLimits行数限制TextFieldLineLimits.Default
leadingIcon@Composable (() -> Unit)?前置图标null
trailingIcon@Composable (() -> Unit)?后置图标null
onTextLayoutDensity.(getResult: () -> TextLayoutResult?) -> Unit文本布局回调(带 Density 接收)null
interactionSourceMutableInteractionSource?交互源null
cursorBrushBrush光标画刷SolidColor(colors.borderColor)
outputTransformationOutputTransformation?输出变换器null
scrollStateScrollState滚动状态rememberScrollState()

TextFieldDefaults 对象

TextFieldDefaults 对象提供了 TextField 组件的默认值。

常量

常量名类型说明默认值
CornerRadiusDp输入框圆角半径10.dp
InsideMarginDpSizeRectangle 模式内部边距DpSize(16.dp, 12.dp)
LineInsideMarginDpSizeLine 模式内部边距DpSize(0.dp, 15.dp)
NoneInsideMarginDpSizeNone 模式内部边距DpSize(0.dp, 9.dp)
CounterFontSizeTextUnit字数统计文字字号10.sp

insideMargin() 函数

TextFieldDefaults.insideMargin(mode: TextFieldMode): DpSize 返回指定背景模式的默认内部边距。

textStyle() 函数

TextFieldDefaults.textStyle(mode: TextFieldMode): TextStyle 返回 COUI 默认输入文本样式:16sp 常规字重,Rectangle 模式下加粗。

textFieldColors() 工厂

构造 [TextFieldColors] 实例。按需覆盖任意子集,未指定的参数回退到 COUI 主题默认值。

参数类型默认值
backgroundColorColorColor.Transparent(COUI 矩形模式仅描边无填充)
labelColorColorCOUITheme.colorScheme.onSurfaceSecondary
borderColorColorCOUITheme.colorScheme.primary
unfocusedBorderColorColorCOUITheme.colorScheme.dividerLine
errorColorColorCOUITheme.colorScheme.error
counterColorColorCOUITheme.colorScheme.onSurfaceContainerHigh
iconColorColorCOUITheme.colorScheme.onSurfaceSecondary
disabledTextColorColorCOUITheme.colorScheme.disabledOnSurface

进阶用法

带图标输入框

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "搜索",
    leadingIcon = {
        Icon(
            imageVector = COUIIcons.Search,
            contentDescription = "搜索图标",
            modifier = Modifier.padding(horizontal = 12.dp)
        )
    }
)

密码输入框

kotlin
var password by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }

TextField(
    value = password,
    onValueChange = { password = it },
    label = "密码",
    visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
    trailingIcon = {
        IconButton(
            onClick = { passwordVisible = !passwordVisible },
            modifier = Modifier.padding(end = 12.dp)
        ) {
            Icon(
                imageVector = COUIIcons.Rename,
                tint = if (passwordVisible) COUITheme.colorScheme.primary else COUITheme.colorScheme.onSurfaceSecondary,
                contentDescription = if (passwordVisible) "隐藏密码" else "显示密码"
            )
        }
    }
)

带验证的输入框

kotlin
var email by remember { mutableStateOf("") }
var isError by remember { mutableStateOf(false) }
val errorColor = Color.Red.copy(0.3f)
val emailPattern = remember { Regex("[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+") }

Column {
    TextField(
        value = email,
        onValueChange = {
            email = it
            isError = email.isNotEmpty() && !emailPattern.matches(email)
        },
        label = "电子邮箱",
        colors = TextFieldDefaults.textFieldColors(
            labelColor = if (isError) errorColor else COUITheme.colorScheme.onSurfaceSecondary,
        ),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
    )
    if (isError) {
        Text(
            text = "请输入有效的邮箱地址",
            color = errorColor,
            style = COUITheme.textStyles.body2,
            modifier = Modifier.padding(start = 16.dp, top = 4.dp)
        )
    }
}

自定义样式

kotlin
var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    label = "自定义输入框",
    cornerRadius = 8.dp,
    colors = TextFieldDefaults.textFieldColors(
        backgroundColor = COUITheme.colorScheme.primary.copy(alpha = 0.1f),
    ),
    textStyle = TextStyle(
        fontWeight = FontWeight.Medium,
        fontSize = 16.sp,
        color = COUITheme.colorScheme.primary
    )
)

使用 TextFieldValue

当需要更细致地控制文本选择和光标位置时:

kotlin
var textFieldValue by remember { mutableStateOf(TextFieldValue("")) }

TextField(
    value = textFieldValue,
    onValueChange = { textFieldValue = it },
    label = "高级输入控制",
    // TextFieldValue 提供了对文本、选择范围和光标位置的控制
)

变更日志

基于 Apache-2.0 许可发布