Jetpack Compose(四)-图片组件

一、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 可以加载位于drawabledrawable-hdpi等文件夹内drawable类型的以<vector></vector>为根节点的图片,普通jpgpngwebp<shape></shape>类型的图片加载会直接报错。不能加载mipmap文件夹内资源。
bitmap 可以加载位于drawabledrawable-hdpi等文件夹内drawable类型的普通jpgpngwebp图片,<vector></vector><shape></shape>图片会报错。不能加载mipmap文件夹内资源。
painter drawable资源:支持加载jpgpngwebp<vector></vector>资源,不支持加载<shape></shape>资源; mipmap资源:支持加载jpgpng资源, 不支持加载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有三种修改方式:tintcolorMatrixlighting

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效果

参考了以下内容

Jetpack Compose 从入门到实战

Jetpack Compose博物馆

相关推荐
whysqwhw20 分钟前
OkHttp PublicSuffix包的后缀列表处理
android
yeziyfx1 小时前
kotlin中集合的用法
android·开发语言·kotlin
EngZegNgi2 小时前
安卓应用启动崩溃的问题排查记录
android·crash·启动崩溃
火柴就是我3 小时前
每日见闻之Container Decoration
android·flutter
天枢破军3 小时前
【AOSP】解决repo拉取提示无法连接android.googlesource.com
android
whysqwhw3 小时前
OkHttp之AndroidPlatform类分析
android
XiaolongTu3 小时前
Kotlin Flow详述:从一个“卡顿”问题到线程切换的本质
android·面试
Kapaseker3 小时前
全网最详细的Compose Stable讲解,你一定要看
android
solo_993 小时前
使用Android Studio 聊微信
android
whysqwhw4 小时前
OkHttp PublicSuffix包的平台化设计分析
android