Android Jetpack Compose学习—— 各种控件的用法
Posted yubo_725
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Jetpack Compose学习—— 各种控件的用法相关的知识,希望对你有一定的参考价值。
前言
Jetpack Compose主要是用来写android UI的,Android UI无外乎文本、图片、列表等各种控件的展示,这里我用的“控件”一词不确定是否准确,因为传统的Android UI确实是一个个控件,而在Jetpack Compose中,类似Text
Image
Column
Row
等其实是用Kotlin写的一个函数,这个函数会渲染出对应的文本、图片、列表等。今天记录的主要是这些“控件”的使用方法。
Text
使用Text
可以显示一行文本,下面的代码展示了Text
的一些用法:
@Preview
@Composable
fun TextTest()
Text(
text = "Hello world", // 文本
fontSize = 30.sp, // 字号
fontWeight = FontWeight.Bold, // 加粗
fontStyle = FontStyle.Italic, // 斜体
fontFamily = FontFamily.Serif, // 字体
color = Color.White, // 颜色
textAlign = TextAlign.Center, // 居中对齐
modifier = Modifier.background(Color.Gray) // 背景色
.fillMaxWidth() // 横向填充最大
.clickable // 点击事件
Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show()
)
这段代码运行在模拟器上效果如下图:
关于以上代码做如下说明:
-
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( AnnotatedString(text), modifier, color, fontSize, fontStyle, fontWeight, fontFamily, letterSpacing, textDecoration, textAlign, lineHeight, overflow, softWrap, maxLines, emptyMap(), onTextLayout, style )
-
设置字号时使用了
fontSize = 30.sp
这种方式,30.sp
实际上是使用了Kotlin的扩展方法,给Int
类增加了一个sp
方法:@Stable val Int.sp: TextUnit get() = pack(UNIT_TYPE_SP, this.toFloat())
Image
使用Image
可以显示一个图片,加载资源文件中的图片可以用如下方法:
@Preview
@Composable
fun ShowImage()
Column
Image(
painter = painterResource(R.mipmap.avatar), // 加载资源文件中的图片
contentDescription = null,
modifier = Modifier
.size(200.dp) // 图片大小
.clip(CircleShape) // 裁剪成圆形
)
这段代码在AS中预览如下图:
加载本地图片非常容易,如果想加载网络上的图片呢?
这里推荐一个非常好用的图片加载库Coil
经测试,Coil比Glide有更优秀的内存占用,分别使用这两个库加载同一个图片列表,Coil占用的内存大概是Glide的一半,而且Coil完全使用Kotlin编写,其更适用于采用Kotlin开发的Android项目,在Jetpack Compose中使用Coil加载图片如下步骤:
- 添加依赖配置
// 注意这个库并不是Coil库,而是Google封装了Coil用于在Jetpack compose中使用
implementation "com.google.accompanist:accompanist-coil:0.11.1"
- 添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
- 加载网络图片
@Preview
@Composable
fun ShowImage()
Image(
painter = rememberCoilPainter(
request = "https://i02.appmifile.com/778_bbs_en/06/06/2021/efed2421ae.jpg",
previewPlaceholder = R.mipmap.avatar
),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentScale = ContentScale.Crop
)
在模拟器上运行以上代码效果如下:
如果你在跑上述代码时遇到如下错误:
java.lang.IllegalStateException: function = <anonymous>, count = 3, index = 3
at androidx.compose.compiler.plugins.kotlin.lower.ComposerLambdaMemoization.wrapFunctionExpression(ComposerLambdaMemoization.kt:671)
at androidx.compose.compiler.plugins.kotlin.lower.ComposerLambdaMemoization.visitComposableFunctionExpression(ComposerLambdaMemoization.kt:529)
at androidx.compose.compiler.plugins.kotlin.lower.ComposerLambdaMemoization.visitFunctionExpression(ComposerLambdaMemoization.kt:591)
这是Kotlin版本和Compose版本问题导致的,请确保你的Kotlin版本和Compose版本如下(或者更新):
ext.kotlin_version = '1.4.32'
ext.compose_version = '1.0.0-beta07'
LazyColumn / LazyRow
使用LazyColumn
可以很方便的实现自动回收的长列表,其使用方法如下:
@Preview
@Composable
fun TestList()
LazyColumn
items(100) i ->
GenListItem(i)
@Composable
fun GenListItem(index: Int)
// 创建列表Item
Column
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp, 16.dp, 0.dp)
)
Text("List Item $index", fontSize = 15.sp, color = Color.Black)
Divider(Modifier.height(0.4.dp))
在模拟器上运行效果如下图:
LazyRow
则可以创建一个横向滑动的列表,示例代码如下:
@Preview
@Composable
fun TestList()
LazyRow
items(10)
Image(
painter = painterResource(R.mipmap.avatar),
modifier = Modifier.size(100.dp).padding(8.dp),
contentDescription = null
)
运行效果如下:
自定义图形
在传统的Android UI开发中,我们如果要自定义View,一般会自定义一个类继承自View
或者ViewGroup
,然后复写其中的onMeasure
onLayout
onDraw
等方法,但是这套在Jetpack compose中不适用了,因为Jetpack compose是一套声明式的UI,而传统的Android UI开发是命令式UI。Jetpack compose中提供了Canvas用于绘制自定义图形,其使用方法如下:
@Preview
@Composable
fun TestCanvas()
Canvas(modifier = Modifier.fillMaxSize())
val w = size.width
// 画直线
drawLine(
start = Offset(x = 0f, y = 100f), // 起点坐标
end = Offset(x = w, y = 100f), // 终点坐标
color = Color.Black, // 线条颜色
strokeWidth = 10f // 线条粗细
)
// 画圆
drawCircle(
color = Color.Red, // 填充颜色
center = Offset(x = w / 2, y = 220f), // 圆心坐标
radius = 100f // 半径
)
// inset用于调整当前作用域的默认参数,相当于画矩形时将起点坐标各+50
inset(50f, 50f)
drawRect(
color = Color.Blue, // 填充颜色
topLeft = Offset(x = 0f, y = 350f), // 左上角坐标
size = Size(300f, 150f) // 矩形大小(长宽)
)
// rotate将包裹在其中的矩形顺时针旋转30度
rotate(degrees = 30f)
drawRect(
color = Color.Gray,
topLeft = Offset(x = w / 2, y = 900f),
size = Size(200f, 90f)
)
在模拟器上运行效果如下图:
以上是关于Android Jetpack Compose学习—— 各种控件的用法的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack Compose学习—— Jetpack compose基础布局
Android Jetpack Compose学习—— Jetpack compose入门
Android Jetpack Compose学习—— Jetpack compose入门
Android Jetpack Compose学习—— 各种控件的用法