Compose中TextField的简单使用
# 基础API
fun TextField(
value: String, // 文字,也可以传入TextFieldValue
onValueChange: (TextFieldValue) -> Unit, // 文字改变的回调
modifier: Modifier = Modifier, // 修饰符
enabled: Boolean = true, // 是否可用,等价于Android中的enable属性
readOnly: Boolean = false, // 是否只读
textStyle: TextStyle = LocalTextStyle.current, // 文字格式,可以传入SpanStyle和ParagraphStyle
label: @Composable (() -> Unit)? = null, // 标签,跟Material中的label类似
placeholder: @Composable (() -> Unit)? = null, // 输入文本为空的占位符,有焦点才会展示
leadingIcon: @Composable (() -> Unit)? = null, // 头部图标
trailingIcon: @Composable (() -> Unit)? = null, // 尾部图标
isError: Boolean = false, // 指定当前输入文本是否出错,如果为错,则会把文字和线框显示为红色来提示
visualTransformation: VisualTransformation = VisualTransformation.None, // 可以简单的理解为EditText中的inputType
keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 定义软键盘上的返回键的功能,可以定义为return/search等
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() // 用来定义文字,光标等的处于不同状态的颜色
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 基本用法
我们来简单实现一个搜索文本框,左边搜索按钮,点击就提示输入的关键字,右边清除按钮,点击就清除内容,大概效果如下:
用Compose实现的代码如下:
@Composable
fun TextFieldDemo(context: Context) {
// 定义一个可观测的text,用来在TextField中展示
var text by remember {
mutableStateOf("")
}
TextField(
value = text, // 显示文本
onValueChange = { text = it }, // 文字改变时,就赋值给text
label = { Text(text = "Input") }, // label是Input
// 头部图标,设置为搜索
leadingIcon = @Composable {
Image(
imageVector = Icons.Filled.Search, // 搜索图标
contentDescription = null,
modifier = Modifier.clickable { Toast.makeText(context, "search $text", Toast.LENGTH_SHORT).show() }) // 给图标添加点击事件,点击就吐司提示内容
},
// 尾部图标,设置为清除
trailingIcon = @Composable {
Image(imageVector = Icons.Filled.Clear, // 清除图标
contentDescription = null,
modifier = Modifier.clickable { text = "" }) // 给图标添加点击事件,点击就清空text
},
placeholder = @Composable { Text(text = "This is placeholder") }, // 不输入内容时的占位符
)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
效果如下:
现在让我们来添加两行代码:
isError = true, // 展示错误提示
visualTransformation = PasswordVisualTransformation(), // 展示为密文
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), // 将键盘的回车键定义为搜索
// 给回车键定义点击搜索事件,弹出搜索内容
keyboardActions = KeyboardActions(onSearch = { Toast.makeText(context, "search $text", Toast.LENGTH_SHORT).show() })
singleLine = true // 重新定义回车键,一定要定义为单行,否则回车键还是换行,重定义不生效
2
3
4
5
6
然后看下效果:
我们看到,文字和下划线都提示为红色,表示错误,文字显示为密文字,回车键变为搜索,当然,回车键还可以定义为其他类型,比如:Go,Next,Done等,大家可以自行尝试。
现在让我们来添加形状,我们添加这样一行代码:
shape = RoundedCornerShape(16.dp) // 指定圆角矩形
效果如下:
发现是圆角的了,但是却有个下划线,怎么办呢,我们可以指定colors为透明来隐藏下划线,如下:
// 指定下划线颜色
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent, // 有焦点时的颜色,透明
unfocusedIndicatorColor = Color.Green, // 无焦点时的颜色,绿色
errorIndicatorColor = Color.Red, // 错误时的颜色,红色
disabledIndicatorColor = Color.Gray // 不可用时的颜色,灰色
)
2
3
4
5
6
7
我们还要修改
isError = false, // 不展示错误提示
不然下划线就一直是红色的了。好,我们来看效果:
我们看到,当没有焦点时,下划线为绿色,有焦点就看不到了(因为透明),如果想要去掉下划线,可以直接把所有状态下的下划线颜色都设为透明,至于错误和不可用时下划线的颜色,大家可以自行尝试看下效果。
# 扩展
# 1 轮廓式文本框OutlinedTextField
轮廓式文本框OutlinedTextField自带轮廓,也就是只提供描边,可以轻易实现产品和UI眼里的效果,我们来简单写个demo:
@Composable
fun OutlinedTextFieldDemo() {
var text by remember { mutableStateOf("") }
OutlinedTextField(value = text,
label = { Text(text = "Input something") },
onValueChange = { text = it })
}
2
3
4
5
6
7
很简单,API跟TextField都一样的,只是样式不同而已,效果如下:
# 2 基本文本框BasicTextField
BasicTextField可以用来响应硬件或软件盘编辑文字,可以自定义cursor、边框等,但是没有placeholder和label属性。API如下:
fun BasicTextField(
value: String, // 文字,也可以传入TextFieldValue
onValueChange: (String) -> Unit, // 文字改变的回调
modifier: Modifier = Modifier, // 修饰符
enabled: Boolean = true, // 是否可用
readOnly: Boolean = false, // 是否只读
textStyle: TextStyle = TextStyle.Default, // 文字样式
keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 定义软键盘上的返回键的功能,可以定义为return/search等
keyboardActions: KeyboardActions = KeyboardActions.Default, // 按下软键盘上返回键的回调
singleLine: Boolean = false, // 是否是单行
maxLines: Int = Int.MAX_VALUE, // 最大行数
visualTransformation: VisualTransformation = VisualTransformation.None, // 可以简单的理解为EditText中的inputType
onTextLayout: (TextLayoutResult) -> Unit = {}, // 布局变化的回调
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, // 表示一个由组件发出的交互流
cursorBrush: Brush = SolidColor(Color.Black), // 重点!!画刷
decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit = // 用来定义装饰框,innerTextField这个参数就是用来绘制文字的
@Composable { innerTextField -> innerTextField() }
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
我们来写个小demo看下:
@Composable
fun BasicTextFieldDemo() {
var text by remember { mutableStateOf("hello") }
BasicTextField(
value = text,
onValueChange = { text = it },
)
}
2
3
4
5
6
7
8
展示效果如下:
就一个hello...,没有边框,如果你初始值是空,连字都看不到,就是个空白,真是够原始,够基础,确实Basic,现在我们加个背景吧,添加:
modifier = Modifier.background(Color.Green, RoundedCornerShape(8.dp)) // 加一个绿色背景
效果如下:
确实是个绿色背景...,我们来试着加个文本框,添加如下代码
// 画修饰框
decorationBox = @Composable { innerTextField ->
// 先画个圆压压惊
Canvas(modifier = Modifier.size(width = 100.dp, height = 50.dp)) {
drawCircle(color = Color.Red, style = Stroke(width = 1F))
}
// 然后再画文字
innerTextField()
}
2
3
4
5
6
7
8
9
这个其实很简单,可以理解为先绘制一个圆形,然后调用innerTextField()绘制原有的文字,效果如下:
# 总结
如果你想完全自定义文本框,可以使用BasicTextField;
如果你想使用轮廓式文本框,使用OutlinedTextField;
如果你想使用实心文本框,使用TextField即可;
其中TextField和OutlinedTextField除了一个是实心,一个是空心,其他API都是一样的,而BasicTextField则完全是自定义的。
完整代码点: 这里 (opens new window)