Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助您简化并加快 Android 界面开发,在 Google 官方的大力推荐下,我想是时候学习一下了,毕竟这才是真正的现代化 Android 开发。这篇文章主要是记录一下我学习 Jetpack Compose 基础组件的过程。
Text
kotlin
@Composable
fun Text(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
fontStyle: FontStyle? = null,
fontWeight: FontWeight? = null,
fontFamily: FontFamily? = null,
letterSpacing: TextUnit = TextUnit.Unspecified,
textDecoration: TextDecoration? = null,
textAlign: TextAlign? = null,
lineHeight: TextUnit = TextUnit.Unspecified,
overflow: TextOverflow = TextOverflow.Clip,
softWrap: Boolean = true,
maxLines: Int = Int.MAX_VALUE,
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
)
在开发中,我觉得比较常用 Text 的属性就下面这些吧!
kotlin
@Composable
fun TextStudy() {
Text(
text = "Hello Android",
modifier = Modifier
.fillMaxWidth() // 宽度占满
.background(
color = Color.Green,
shape = RoundedCornerShape(5.dp)
) // 设置背景
.clickable {
// 点击事件
},
style = TextStyle(
color = Color.White, // 文本颜色
fontSize = 20.sp, // 字体大小
letterSpacing = 5.sp, // 文字间距
),
// 对齐方式
textAlign = TextAlign.Center,
// 行高间距
lineHeight = 30.sp,
// 溢出处理
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
如果要显示一个富文本的话,可以使用 AnnotatedString。
kotlin
@Composable
fun RichText() {
Text(
buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 20.sp)) {
append("Hello")
}
withStyle(style = SpanStyle(color = Color.Red)) {
append("Android")
}
}
)
}
还有种情况,就是部分文本点击事件的处理,比如上面这段文本,我只想设置 "Android" 这个文本有点击事件的话,可以使用 pushStringAnnotation。
kotlin
@Composable
fun ClickText() {
val annotatedText = buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 20.sp)) {
append("Hello")
}
//将给定的注释附加到下面的文本上,直到 pop 被调用。
pushStringAnnotation(
tag = "click",
annotation = "content"
)
withStyle(style = SpanStyle(color = Color.Red)) {
append("Android")
}
pop()
}
ClickableText(text = annotatedText, onClick = {
annotatedText.getStringAnnotations(
"click", start = it,
end = it
).firstOrNull()?.let {
// "Android" 部分文本点击事件
}
})
}
TextField
kotlin
@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,
supportingText: @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 = TextFieldDefaults.filledShape,
colors: TextFieldColors = TextFieldDefaults.textFieldColors()
)
对于 TextField,我觉得比较常用的属性就下面这几个吧!
kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TextFieldStudy() {
var text by remember { mutableStateOf("") }
TextField(
value = text, onValueChange = {
// 监听值变化
text = it
}, modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
// 单行显示
singleLine = true,
// 提示文本
placeholder = {
Text(text = "提示文本")
},
colors = TextFieldDefaults.textFieldColors(
// 输入的文字颜色
textColor = Color.Black,
// 光标颜色
cursorColor = Color.Black,
// 文本容器颜色
containerColor = Color.White,
// 提示文字颜色
placeholderColor = Color.Gray,
// 聚焦时底部指示器颜色
focusedIndicatorColor = Color.Transparent,
// 不聚焦时指示器颜色
unfocusedIndicatorColor = Color.Transparent
)
)
}
也可以添加一些前置和后置,比方说我们不要提示文本,直接显示在前置上,可以这么干。
kotlin
fun TextFieldStudy() {
var text by remember { mutableStateOf("") }
TextField(
value = text, onValueChange = {
// 监听值变化
text = it
}, modifier = Modifier
.fillMaxWidth(),
// 单行显示
singleLine = true,
leadingIcon = {
Text(text = "邮箱")
},
trailingIcon = {
Text(text = "@qq.com")
}
)
}
效果如下:
还可以添加 label,聚焦的时候会自动改变字体大小,常用于登录界面,登录时密码一般不会显示,所以此时也可以使用 visualTransformation
less
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TextFieldStudy() {
var text by remember { mutableStateOf("") }
TextField(
value = text, onValueChange = {
// 监听值变化
text = it
}, modifier = Modifier
.fillMaxWidth(),
// 单行显示
singleLine = true,
label = {
Text(text = "密码")
},
visualTransformation = PasswordVisualTransformation()
)
}
效果如下所示:
Button
kotlin
@Composable
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = ButtonDefaults.shape,
colors: ButtonColors = ButtonDefaults.buttonColors(),
elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable RowScope.() -> Unit
)
对于 Button,我觉得比较常用的属性就下面这几个吧!
kotlin
@Composable
fun ButtonStudy() {
Button(
onClick = {
// 点击事件
},
// 形状,可以设置圆角。
shape = RoundedCornerShape(8.dp),
// 设置颜色
colors = ButtonDefaults.buttonColors(
// 填充颜色
containerColor = Color.Green,
// 内容颜色
contentColor = Color.Blue,
// 禁用时填充颜色
disabledContainerColor = Color.Gray,
// 禁用时内容颜色
disabledContentColor = Color.White
),
//是否可用
enabled = true
) {
// Button 里面的内容
Text(text = "Hello")
}
}
如果想要获取 Button 的状态,比如按下和松开想展示不同的 UI 效果,可以这样干:
kotlin
@Composable
fun ButtonStudy() {
// 获取 Button 状态
val btnState = remember {
MutableInteractionSource()
}
val state = if (btnState.collectIsPressedAsState().value) {
// 按下状态
ButtonState(Color.White, Color.Blue)
} else {
ButtonState(Color.Black, Color.White)
}
Button(
onClick = {
// 点击事件
},
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
containerColor = state.btnColor,
),
interactionSource = btnState
) {
Text(text = "Hello", color = state.textColor)
}
}
Image
kotlin
@Composable
fun Image(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
)
对于 Image,我觉得比较常用的属性就下面这几个吧!
kolin
@Composable
fun ImageStudy() {
// 通过 Surface 设置图片形状和边框
Surface(shape = CircleShape, border = BorderStroke(1.dp, Color.Red)) {
Image(
painter = painterResource(id = R.drawable.img),
contentDescription = null,
// 图片大小
modifier = Modifier.size(30.dp, 30.dp),
// 缩放规则
contentScale = ContentScale.Crop
)
}
}