一、Icon
Icon
组件用于显示一系列小图标。Icon
组件支持三种不同类型的图片设置:
kotlin
@Composable
@NonRestartableComposable
fun Icon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current) //染色,默认黑色
) {...}
kotlin
@Composable
@NonRestartableComposable
fun Icon(
bitmap: ImageBitmap,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
) {...}
kotlin
@Composable
fun Icon(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
) {...}
使用示例
kotlin
@Composable
fun Greeting() {
Column {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_launcher_background),
contentDescription = "矢量图资源",
modifier = Modifier.size(150F.dp),
tint = Color.Unspecified <----------注意不加这个就是显示一张纯黑的图片,下同
)
Icon(
bitmap = ImageBitmap.imageResource(R.drawable.rabit4),
contentDescription = "图片资源",
modifier = Modifier.size(150F.dp),
tint = Color.Unspecified
)
Icon(
painter = painterResource(id = R.mipmap.rabit2),
contentDescription = "任意类型资源",
modifier = Modifier.size(150F.dp),
tint = Color.Unspecified
)
}
}
每一种方式有不同的加载图片范围,不然就会报错,具体见下表
加载方式 | 加载图片的范围 |
---|---|
imageVector | 可以加载位于drawable 、drawable-hdpi 等文件夹内drawable类型的以<vector></vector> 为根节点的图片,普通jpg 、png 、webp 、<shape></shape> 类型的图片加载会直接报错。不能加载mipmap 文件夹内资源。 |
bitmap | 可以加载位于drawable 、drawable-hdpi 等文件夹内drawable类型的普通jpg 、png 、webp 图片,<vector></vector> 、<shape></shape> 图片会报错。不能加载mipmap 文件夹内资源。 |
painter | drawable 资源:支持加载jpg ,png ,webp ,<vector></vector> 资源,不支持加载<shape></shape> 资源; mipmap 资源:支持加载jpg ,png 资源, 不支持加载webp 资源 |
contentDescription
参数服务于系统的无障碍功能,其中的文字会转换为语言供视障人士听取内容时使用,这个参数没有默认值,必须手动设置,也是官方有意为之,提醒开发者重视对于残障人士的关怀。但是contentDescription
允许设置为null。
Icon
可以加载网络图片吗?Icon
主要设计是为了加载本地资源,如果加载网络图片请使用Image
组件。后面会讲到。
二、IconButton
IconButton
可以帮助我们生成一个可点击的图标按钮。
kotlin
@Composable
fun IconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true, //是否允许输入性事件
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, //自定义外观行为
content: @Composable () -> Unit //定义在IconButton上绘制的图标
) {...}
IconButton
是一个可点击的图标,用于表示动作(复制,粘贴,保存,等等)。IconButton
的整体最小触摸目标尺寸为 48 x 48dp
,以满足无障碍准则。content
会在 IconButton
内居中。
这个组件通常用于应用栏内的导航图标/动作。content
通常应该是一个图标,使用 androidx.compose.material.icons.Icons
中的一个图标。如果使用自定义图标,请注意内部图标的典型尺寸是 24 x 24 dp
。
比如下面的示例(来自Jetpack Compose 博物馆):
kotlin
@Composable
fun IconButtonDemo() {
Row{
IconButton(onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Search, null)
}
IconButton(onClick = { /*TODO*/ }) {
Icon(Icons.Filled.ArrowBack, null)
}
IconButton(onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Done, null)
}
}
}
UI效果
如果想去掉水波纹,只需要把IconButton
的源码复制到项目中把indication
修改为null
即可,如下:
kotlin
@Composable
fun MyIconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit
) {
Box(
modifier = modifier
.minimumInteractiveComponentSize()
.clickable(
onClick = onClick,
enabled = enabled,
role = Role.Button,
interactionSource = interactionSource,
indication = null <------------变化在这里
),
contentAlignment = Alignment.Center
) {
val contentAlpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
CompositionLocalProvider(LocalContentAlpha provides contentAlpha, content = content)
}
}
三、Image
Image
组件用来显示一张图片。它和Icon
一样也支持三种类型的图片设置,这里以Painter
类型的组件为例,展示一下它的参数列表:
kotlin
fun Image(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center, //定义画笔在给定绘制范围内的对齐方式
contentScale: ContentScale = ContentScale.Fit, //指定图片在Image组件中的伸缩样式,类似传统视图ImageView的scaleType属性
alpha: Float = DefaultAlpha, //画笔透明度
colorFilter: ColorFilter? = null //颜色过滤器
) {...}
①alignment
参数定义画笔在给定绘制范围内的对齐方式,主要有下面这些:TopStart、TopCenter、TopEnd、CenterStart、Center、CenterEnd、BottomStart、BottomCenter、BottomEnd、Top、CenterVertically、Bottom、Start、CenterHorizontally、End
。
②contentScale
指定图片在Image组件中的伸缩样式,类似传统视图ImageView的scaleType属性,具体如下:
ContentScale类型 | 说明 |
---|---|
ContentScale.Crop | 居中裁剪类似ScaleType.centerCrop |
ContentScale.Fit | 类似ScaleType.fitCenter |
ContentScale.FillHeight | 充满高 |
ContentScale.FillWidth | 充满宽 |
ContentScale.Inside | 类似ScaleType.centerInside |
ContentScale.None | 不处理 |
ContentScale.FillBounds | 类似ScaleType.fitXY拉伸撑满宽高 |
③colorFilter
参数用来设置一个ColorFilter
,它可以通过对绘制的图片的每个像素颜色进行修改,以实现不同的图片效果。ColorFilter
有三种修改方式:tint
、colorMatrix
、lighting
。
kotlin
//tint用BlendModel混合指定颜色。其中参数color将用来混合原图片每个像素的颜色
//参数blendModel是混合的模式,blendModel有多种混合模式
//跟传统视图中用的Xfermode的PorterDuff.Model类似
ColorFilter.tint (color:Color,blendMode:BlendMode=BlendMode.SrcIn)
//colorMatrix通过传入一个RGBA四通道的4×5的数字矩阵去处理颜色变化
//比如可以降低图片饱和度,以达到图片灰化的目的
ColorFilter.colorMatrix(colorMatrix:ColorMatrix)
//1ighting用来为图片应用一个简单的灯光效果
//它由两个参数定义,第一个用于颜色相乘,第二个用于添加到原图颜色
ColorFilter.lighting(multiply:Color,add:Color)
1、例子一:圆角带边框图片
代码
kotlin
@Composable
fun Greeting() {
Surface(
modifier=Modifier.background(Color.Black),
shape = CircleShape,
border = BorderStroke(2.dp, Color.Yellow)
) {
Image(
painter = painterResource(id = R.mipmap.rabit2),
contentDescription = null,
modifier = Modifier.size(200.dp),
contentScale = ContentScale.Crop
)
}
}
UI效果
2、例子二:加载网络图片
用Coil加载网络图片
kotlin
@Composable
fun Greeting() {
Image(
painter = rememberAsyncImagePainter(model = "https://png.pngtree.com/png-clipart/20220809/ourmid/pngtree-rabbit-cartoon-cute-little-white-rabbit-head-png-image_6104184.png"),
contentDescription = null
)
}
UI效果
3、例子三:加载svg图片且支持无损缩放
添加依赖
kotlin
implementation "io.coil-kt:coil-compose:2.2.0"
implementation "com.github.skydoves:landscapist-coil:2.1.2"
implementation "io.coil-kt:coil-svg:2.2.0"
代码
kotlin
@Composable
fun Greeting() {
val context = LocalContext.current
val imageLoader = // 添加 SVG 解码器
ImageLoader.Builder(context)
.components {
// 添加 SVG 解码器
add(SvgDecoder.Factory())
}.build()
var flag by remember { mutableStateOf(false) }
val size by animateDpAsState(targetValue = if(flag) 450.dp else 50.dp, label = "")
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column {
CoilImage(
imageModel = {"https://coil-kt.github.io/coil/images/coil_logo_black.svg"},
modifier = Modifier
.size(size)
.clickable(
onClick = {
flag = !flag
},
indication = null,
interactionSource = MutableInteractionSource()
),
imageLoader = {imageLoader}
)
}
}
}
UI效果