Jetpack Compose | 控件篇(二) -- Icon,Image

2,642 阅读3分钟

写在最前

在上一篇,我们学习了Compose 中的 Text 、TextField 、Button,并在WorkShop中进行了一系列尝试。 除了对他们的效果有了直观的认识外,也感受了Compose的编码乐趣。

本篇我们将继续学习Icon和Image,从命名上我们可以看出他们和 图形、图片 有关,也是 内容呈现 中非常重要的一种载体和方式。

文中代码均基于 1.0.1版本

如无特殊说明,文中的 Compose 均指代 Jetpack compose

文中代码均可在 WorkShop 中获取,本篇代码集中于 post27 包下

Icon

使用方法

翻阅源码,我们可以获知有三个函数用于构建Icon组件。

分别是:

fun Icon(
    imageVector: ImageVector,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
fun Icon(
    bitmap: ImageBitmap,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
fun Icon(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)

不难发现,仅第一个形参类型不一致,但均是Icon的实际内容。

而其他三个参数,含义分别为:

  • contentDescription: 内容含义描述,用于 无障碍服务 ,如果这个Icon可以被触发,就需要解释它的含义,如果仅仅是装饰性质,可以忽略掉
  • modifier: 修饰器
  • tint: 着色器,可以直接修改Icon实质内容的颜色。从事Android行业的读者并不陌生

而实质内容可以以三种方式进行描述:

  • ImageVector 矢量图
  • ImageBitmap 位图
  • Painter 可被绘制的内容,这是一个抽象的类,类似于Android中的 Drawable

效果

Compose中已经存在一些矢量图资源,例如:

public val Icons.Filled.Favorite: ImageVector
    get() {
        if (_favorite != null) {
            return _favorite!!
        }
        _favorite = materialIcon(name = "Filled.Favorite") {
            materialPath {
                moveTo(12.0f, 21.35f)
                lineToRelative(-1.45f, -1.32f)
                curveTo(5.4f, 15.36f, 2.0f, 12.28f, 2.0f, 8.5f)
                curveTo(2.0f, 5.42f, 4.42f, 3.0f, 7.5f, 3.0f)
                curveToRelative(1.74f, 0.0f, 3.41f, 0.81f, 4.5f, 2.09f)
                curveTo(13.09f, 3.81f, 14.76f, 3.0f, 16.5f, 3.0f)
                curveTo(19.58f, 3.0f, 22.0f, 5.42f, 22.0f, 8.5f)
                curveToRelative(0.0f, 3.78f, -3.4f, 6.86f, -8.55f, 11.54f)
                lineTo(12.0f, 21.35f)
                close()
            }
        }
        return _favorite!!
    }

当然,按照 MaterialDesign, 存在一系列的风格:

  • Filled 默认,图形是内容填充风格
  • Outlined 只有描边,不做填充
  • Rounded 圆形,例如圆形启动图标
  • TwoTone 双调,不确定doc是否写错,和Sharp完全一致,可以看情况搭讪下设计MM,顺带提升下审美
  • Sharp 例如直角图标

均可以在Google Fonts进行定制与体验

Icon(
    Icons.Filled.Call,
    contentDescription = "Call"
)
Icon(
    Icons.Outlined.Call,
    contentDescription = "Call"
)
Icon(
    Icons.Rounded.Call,
    contentDescription = "Call"
)
Icon(
    Icons.TwoTone.Call,
    contentDescription = "Call"
)
Icon(
    Icons.Sharp.Call,
    contentDescription = "Call"
)

选取了部分内置图标进行直观感受。

三种资源使用方式以及Tint:

Icon(
    ImageBitmap.imageResource(id = R.drawable.baseline_fingerprint_black_24dp),
    contentDescription = "Check fingerprint",
    tint = Color.Green
)

icon_demo.webp

Image

使用方式

和Icon的使用类似,同样有三个函数:

fun Image(
    bitmap: ImageBitmap,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
)
fun Image(
    imageVector: ImageVector,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
)
fun Image(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
)

和Icon对比,如下参数不同:

  • alignment: 内容对齐方式
  • contentScale: 缩放,类似Android ScaleType
  • alpha: 内容的Alpha通道
  • colorFilter: 色彩过滤器,可以实现tint、滤镜矩阵等,非Compose特有,不再展开

值得一提的是, 图片因其信息量大的特性,实际应用过程中,对于远程资源,总是需要考虑:

  • 加载耗时
  • 清晰度分级
  • 缓存

等内容,本篇我们仅学习静态资源的加载, 而和Compose相关的 资源 加载函数,在Icon中已经有代码示例,本节不再赘述。

结语

又很愉快地学完了一些新知识,当然,在Icon和Image中,依旧存在很多我们没有挖掘的内容,但不用着急,在起始阶段,我们仅需要掌握控件的特性和使用方式。

当我们掌握了UI布局相关的内容后,我们会回过头来,再学习他的原理部分。

打个招呼:其实起始阶段的内容都非常简单,但因为我最近比较懒,而且正在处理一件有挑战的事情,占用了很多精力,所以更新有点拖沓