图片位置
图片存放位置(drawable 还是 mipmap)的选择主要取决于图片的用途:
drawable 文件夹:
- 用于存放应用中大多数图片资源,如按钮图标、背景图、插图等。
- 支持多种密度限定符(如 drawable-hdpi、drawable-xhdpi 等)。
- 在 Compose 中通过
painterResource(id = R.drawable.image_name) 访问。
mipmap 文件夹:
- 专门用于存放应用图标(launcher icon)
- 系统会对 mipmap 中的图标进行特殊处理,确保在不同场景下(如 launcher、快捷方式等)显示质量。
- 在 Compose 中通过
painterResource(id = R.mipmap.ic_launcher) 访问。
最佳实践:
- 将应用图标放在 mipmap 文件夹
- 其他所有图片资源放在 drawable 文件夹
在 Compose 中加载方式相同,都是使用 painterResource(),区别仅在于资源 ID 来自 R.drawable 还是 R.mipmap。
引用
1
| import androidx.compose.foundation.Image
|
属性
适配模式
1 2 3 4 5 6 7 8 9
| Image( modifier = Modifier .padding(10.dp) .size(200.dp, 150.dp) .background(color = Color.Yellow), painter = painterResource(id = R.drawable.logo), contentDescription = null, contentScale = ContentScale.Crop )
|
contentScale:
ContentScale.Fit 等比缩放 保证图片完全显示 默认的方式
ContentScale.Crop 等比缩放后居中剪裁
ContentScale.Inside 等比缩放保证图片完全显示
ContentScale.FillBounds 拉伸填充
ContentScale.FillHeight 等比缩放 填充高度
ContentScale.FillWidth 等比缩放 填充宽度
ContentScale.None 不缩放后居中剪裁
着色
非透明的PNG图片的区域添加着色。
1 2 3 4 5 6 7 8
| Image( modifier = Modifier .padding(10.dp) .size(200.dp, 150.dp), painter = painterResource(id = R.drawable.logo), contentDescription = null, colorFilter = ColorFilter.tint(color = Color.Green, BlendMode.SrcAtop) )
|
圆角
圆形
1 2 3 4 5 6 7 8 9 10
| Image( modifier = Modifier .padding(10.dp) .size(200.dp) .background(color = Color.Yellow) .clip(shape = CircleShape), painter = painterResource(id = R.drawable.logo), contentDescription = null, contentScale = ContentScale.Crop, )
|
圆角
1 2 3 4 5 6 7 8 9 10
| Image( modifier = Modifier .padding(10.dp) .size(200.dp) .background(color = Color.Yellow) .clip(shape = RoundedCornerShape(20.dp)), painter = painterResource(id = R.drawable.logo), contentDescription = null, contentScale = ContentScale.Crop, )
|
背景剪裁
图片的背景是不会被剪裁的,我们可以在外面套一个Box做剪裁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Box( modifier = Modifier .padding(10.dp) .size(200.dp) .clip(shape = RoundedCornerShape(20.dp)), ) { Image( painter = painterResource(id = R.drawable.logo), contentDescription = null, modifier = Modifier .background(color = Color.Yellow) .fillMaxSize(), contentScale = ContentScale.Crop ) }
|
加载本地图片
1 2 3 4
| Image( painter = painterResource(R.drawable.my_image), contentDescription = "My Image" )
|
图片角标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Image( painter = painterResource(id = R.drawable.logo), modifier = Modifier .padding(10.dp) .size(46.dp) .drawWithContent { drawContent() drawCircle( Color.Red, 5.dp.toPx(), Offset(size.width - 1.dp.toPx(), 1.dp.toPx()) )
}, contentDescription = "头像" )
|
加载网络图片
Github地址:https://github.com/coil-kt/coil
Coil官方文档:https://coil-kt.github.io/coil
添加依赖
1
| implementation("io.coil-kt:coil-compose:2.6.0")
|
添加网络权限
1
| <uses-permission android:name="android.permission.INTERNET" />
|
使用
1 2 3 4 5 6 7
| @Composable fun LoadWebImage(url:String){ AsyncImage( model = url, contentDescription = null, ) }
|
调用
1
| LoadWebImage(url = "https://www.psvmc.cn/head.jpg")
|
设置占位图
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Composable fun LoadWebImage(url:String){ AsyncImage( model = ImageRequest.Builder(LocalContext.current) .data(url) .crossfade(true) .build(), placeholder = painterResource(R.drawable.ic_launcher_foreground), contentDescription = stringResource(R.string.app_name), contentScale = ContentScale.Crop, modifier = Modifier.clip(CircleShape).size(60.dp) ) }
|
加载GIF
添加引用
1 2
| implementation("io.coil-kt:coil-compose:2.6.0") implementation("io.coil-kt:coil-gif:2.6.0")
|
加载GIF
1 2 3 4 5 6 7 8
| val imageLoader = ImageLoader.Builder(LocalContext.current).components { if (SDK_INT >= 28) { add(ImageDecoderDecoder.Factory()) } else { add(GifDecoder.Factory()) } }.build()
|
本地GIF
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Image( modifier = Modifier .size(64.dp) .align(Alignment.Center) .background(Color(0xffffffff),RoundedCornerShape(10.dp)) .clip(shape = RoundedCornerShape(10.dp)), painter = rememberImagePainter( data = R.drawable.loading, imageLoader = imageLoader, builder = { crossfade(true) }), contentDescription = null )
|
网络GIF
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Image( modifier = Modifier .size(64.dp) .align(Alignment.Center) .background(Color(0xffffffff),RoundedCornerShape(10.dp)) .clip(shape = RoundedCornerShape(10.dp)), painter = rememberImagePainter( data = "https://www.psvmc.cn/loading.gif", imageLoader = imageLoader, builder = { crossfade(true) }), contentDescription = null )
|
自带的加载中
1 2 3 4 5
| CircularProgressIndicator( modifier = Modifier .size(30.dp) .align(Alignment.Center) )
|
加载Bitmap
1 2 3 4 5 6 7 8 9 10 11 12
| @Composable fun ZImgLocalBitmap(bitmap: Bitmap) { val imageBitmap = bitmap.asImageBitmap() Image( bitmap = imageBitmap, contentDescription = null, modifier = Modifier .fillMaxSize(), contentScale = ContentScale.FillBounds ) }
|