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博物馆

相关推荐
拭心9 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王12 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡12 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道12 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库13 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道14 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe14 小时前
Android Hook - 动态加载so库
android
居居飒15 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He17 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗18 小时前
Android笔试面试题AI答之Android基础(1)
android