目录
- 初识 Jetpack Compose(一) :Hello,Jetpack Compose!
- 初识 Jetpack Compose(二) :布局
- 初识 Jetpack Compose(三) :修饰符(Modifier)
- 初识 Jetpack Compose(四) :主题
- 初识 Jetpack Compose(五) :组件-Text
- 初识 Jetpack Compose(六) :组件-Text fields
一、TextFiled
fun TextField(
// 文字,另外一个构造函数可传入TextFieldValue
value: String,
// 内容变化回调监听
onValueChange: (TextFieldValue) -> Unit,
// 修饰符
modifier: Modifier = Modifier,
// 是否可用
enabled: Boolean = true,
// 是否只读
readOnly: Boolean = false,
// 文字样式
textStyle: TextStyle = LocalTextStyle.current,
// 标签(一个辅助提示文案)
label: @Composable (() -> Unit)? = null,
// 内容占位符,类似于hint,组件处于焦点时显示
placeholder: @Composable (() -> Unit)? = null,
// 头部图标
leadingIcon: @Composable (() -> Unit)? = null,
// 尾部图标
trailingIcon: @Composable (() -> Unit)? = null,
// 指定当前输入文本是否出错,如果为错,则会把文字和线框显示为红色来提示
isError: Boolean = false,
// 输入值样式,比如显示密码(PasswordVisualTransformation())
visualTransformation: VisualTransformation = VisualTransformation.None,
// 定义软键盘上的返回键的功能,如 return/search 等
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
// 按下软键盘上 action 的回调
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()
)
复制代码
1.1. 管理状态
注意: 在Compose 编程思想中有讲到,当页面数据发生变化时,以前的 Android 布局一般需要使用 findViewById()
等函数遍历树,并通过调用诸如 setText(String)
等方法进行数据更改。这样会导致在项目在年月的更迭中维护和阅读成本逐渐变高,相信这一点很多小伙伴都深有体会。而Compose
只会在页面数据发生变化时再去重绘。官方描述如下:
长期以来,Android 视图层次结构一直可以表示为界面微件树。由于应用的状态会因用户交互等因素而发生变化,因此界面层次结构需要进行更新以显示当前数据。最常见的界面更新方式是使用
findViewById()
等函数遍历树,并通过调用button.setText(String)
、container.addChild(View)
或img.setImageBitmap(Bitmap)
等方法更改节点。这些方法会改变微件的内部状态。
手动操纵视图会提高出错的可能性。如果一条数据在多个位置呈现,很容易忘记更新显示它的某个视图。此外,当两项更新以意外的方式发生冲突时,也很容易造成异常状态。例如,某项更新可能会尝试设置刚刚从界面中移除的节点的值。一般来说,软件维护复杂性会随着需要更新的视图数量而增长。
在过去的几年中,整个行业已开始转向声明性界面模型,该模型大大简化了与构建和更新界面关联的工程设计。该技术的工作原理是在概念上从头开始重新生成整个屏幕,然后仅执行必要的更改。此方法可避免手动更新有状态视图层次结构的复杂性。Compose 是一个声明性界面框架。
重新生成整个屏幕所面临的一个难题是,在时间、计算能力和电池用量方面可能成本高昂。为了减轻这一成本,Compose 会智能地选择在任何给定时间需要重新绘制界面的哪些部分。这会对您设计界面组件的方式有一定影响,如重组中所述。
所以,Compose
不会每时每刻自动更新,而是必须明确获知新状态,才能相应地进行更新,所以!TextField
不会自行更新,但会在其 value
参数更改时更新。这就导致我们需要在TextFiled
的输入监听中记录value
改变的值,然后将这个值指向TextFiled
的value
。比如:
//这样在软键盘输入值会触发 onValueChange 监听,但 TextField 的值不会改变
@Composable
fun inputPhone(){
TextField(value = "", onValueChange = {})
}
复制代码
需要这样记录下监听到的值,然后再将值指向value
,TextField
得知value
发生改变,则会去重绘UI。想更深入了解的小伙伴可以去看官方文档-管理状态一文。
@Composable
fun inputPhone(){
var phone by rememberSaveable { mutableStateOf("") }
TextField(value = phone, onValueChange = {
phone = it
})
}
复制代码
1.2. 使用示例
@Composable
fun inputPhone() {
var phone by rememberSaveable { mutableStateOf("") }
TextField(
modifier = Modifier.background(Color.Cyan).fillMaxWidth(),
value = phone,
label = { Text(text = "Phone") },
placeholder = { Text(text = "Input your phone number please.") },
leadingIcon = {
Icon(imageVector = Icons.Filled.Phone, contentDescription = null)
},
trailingIcon = {
Icon(imageVector = Icons.Filled.Clear, contentDescription = null,Modifier.clickable {
//清空内容,改变phone的值就行
phone = ""
})
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next,keyboardType = KeyboardType.Phone),
singleLine = true,
onValueChange = {
phone = it
})
}
复制代码
二、OutlinedTextField
OutlinedTextField
的构造参数与TextFiled
完全一致,正如其名一样,它给输入框提供了外边框,所以OutlinedTextField
与 TextFiled
的区别仅为外观不一样。
三、BasicTextField
BasicTextField
更像是 xml 中的 EditText
,因为它没有其他的一些装饰,就是一个普通的输入框。其构可构造参数与 TextFiled
大致相同,下面列出独有的参数。
fun BasicTextField(
...
//布局发生变化回调
onTextLayout: (TextLayoutResult) -> Unit = {},
// 画笔/画刷?
cursorBrush: Brush = SolidColor(Color.Black),
// 定义装饰框
decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
@Composable { innerTextField -> innerTextField() }
)
复制代码
四、最后
好记性不如烂笔头,初识 Jetpack Compose
系列是我自己的学习笔记,在加深知识巩固的同时,也可以锻炼一下写作技能。文章中的内容仅作参考,如有问题请留言指正。