Image的源码参数预览
@Composable
fun Image(painter: Painter,contentDescription: String?,modifier: Modifier = Modifier,alignment: Alignment = Alignment.Center,contentScale: ContentScale = ContentScale.Fit,alpha: Float = DefaultAlpha,colorFilter: ColorFilter? = null
)
目前在 Compose
中 Image
有三种,详情可先在官网中找到
Image
可以帮我们加载一张图片
@Composable
fun ImageScreen1() {Image(painter = painterResource(id = R.drawable.ic_launcher_background),contentDescription = null)
}@Preview(showBackground = true)
@Composable
fun ImageScreenPreview1() {ImageScreen1()
}
图片大小
我们可以使用 Modifier.size()
来设置图片大小。
@Composable
fun ImageScreen1() {Image(painter = painterResource(id = R.drawable.ic_launcher_foreground),contentDescription = null,modifier = Modifier.size(350.dp))
}
图片形状
我们可以使用 Surface
来帮助我们设置形状,或者在 Image 组件中使用 modifier.clip() 来裁剪形状。
@Composable
fun ImageScreen() {Surface(shape = CircleShape) {Image(painter = painterResource(id = R.drawable.wallpaper),contentDescription = null,modifier = Modifier.size(350.dp))}}
是不是有一点小问题?似乎只有左右两边变成了圆形,而上下并没有。
这是因为 Image
中源码的 contentScale
参数默认是 ContentScale.Fit
,
也就是保持图片的宽高比,缩小到可以完整显示整张图片。
而 ContentScale.Crop
也是保持宽高比,但是尽量让宽度或者高度完整的占满。
所以我们将 contentScale
设置成 ContentScale.Crop
。
@Composable
fun ImageScreen() {Surface(shape = CircleShape) {Image(painter = painterResource(id = R.drawable.wallpaper),contentDescription = null,modifier = Modifier.size(350.dp),contentScale = ContentScale.Crop)}}
图像边框
你可以利用 Surface
中的 border
参数来设置边框。
@Composable
fun ImageScreen() {Surface(shape = CircleShape,border = BorderStroke(5.dp, Color.Gray)) {Image(painter = painterResource(id = R.drawable.wallpaper),contentDescription = null,modifier = Modifier.size(350.dp),contentScale = ContentScale.Crop)}
}
使用 Coil 来动态加载图片
Compose 自带的 Image
只能加载资源管理器中的图片文件,如果想加载网络图片或者是其他本地路径下的文件,则需要考虑其他的库,比如 Coil
<uses-permission android:name="android.permission.INTERNET" />
implementation("io.coil-kt:coil-compose:2.4.0")
Image(painter = rememberAsyncImagePainter(data = "https://picsum.photos/300/300"),contentDescription = null
)
加载Gif图像
implementation("io.coil-kt:coil-gif:2.4.0") // KTS
val gif_url="https://s1.chu0.com/src/img/gif/db/dba873378578488a9de51f01c101cd6a.gif?e=1735488000&token=1srnZGLKZ0Aqlz6dk7yF4SkiYf4eP-YrEOdM1sob:ENutG45YK-AdEpn2dSKWQRZ_8qY="val imageLoader = ImageLoader.Builder(context).components {if (SDK_INT >= 28) {add(ImageDecoderDecoder.Factory())} else {add(coil.decode.GifDecoder.Factory())}}.build()Image(painter = rememberAsyncImagePainter(gif_url,imageLoader = imageLoader),contentDescription = null
)
加载 Svg 图像
Coil
可以加载 Svg 图像
添加依赖
implementation("io.coil-kt:coil-svg:2.4.0") // KTS
val imageLoader = ImageLoader.Builder(context).components {add(SvgDecoder.Factory(true))}.build()Image(painter = rememberAsyncImagePainter(data = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",imageLoader = imageLoader),contentDescription = null
)
放大缩小 Svg 图像文件
虽然 Coil 可以显示 Svg 图像,但是如果在我们的 app 中,需要动态的放大 Svg 图像,那么你大概率会得到强行拉升 Svg 像素后的图像,而不是无损放大
导致的原因可能是 Coil 中的 ImageLoader 会把 Svg 转换成位图,而不是安卓的矢量图 vector drawable, 而位图则不能无损放大
val context = LocalContext.current
val imageLoader = ImageLoader.Builder(context).componentRegistry {add(SvgDecoder(context))}.build()var flag by remember { mutableStateOf(false) }
val size by animateDpAsState(targetValue = if(flag) 450.dp else 50.dp)Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center
) {Column {Image(painter = rememberAsyncImagePainter(data = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",imageLoader = imageLoader),contentDescription = null,modifier = Modifier.size(size).clickable(onClick = {flag = !flag},indication = null,interactionSource = MutableInteractionSource()))}
}
那么要解决这个问题,就是尝试实现 svg 转换为 vector drawable, 需要添加三方依赖
Landscapist
implementation "com.github.skydoves:landscapist-coil:1.3.2"
CoilImage(imageModel = "https://coil-kt.github.io/coil/images/coil_logo_black.svg",contentDescription = null,modifier = Modifier.size(size).clickable(onClick = {flag = !flag},indication = null,interactionSource = MutableInteractionSource()),imageLoader = imageLoader
)
Image 参数详情
Ucrop 一个图片裁剪库
Coil