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

相关推荐
千里马学框架3 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077006 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼7 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone8 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen8 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone8 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui