Jetpack撰写:类似于内置`Icons.Default`

时间:2020-11-05 15:20:34

标签: kotlin android-jetpack kotlin-android-extensions android-vectordrawable android-jetpack-compose

看来,从res文件夹中的Android Vector Resources中加载自定义图标的唯一方法是使用@Composable方法在vectorResource(R.drawable.myVectorName)函数中完成。

这很不错,但我喜欢为VectorAssets类获取Icon(asset: VectorAsset)的语法,看起来像Icon(Icons.Default.Plus)

似乎vectorResource()方法使用称为loadVectorResource()内部方法,并且用于读取构成矢量资产文件的实际XML文件的方法也是内部的

我该如何在Jetpack Compose中创建像MyAppIcons.Default.SomeIcon这样的对象?

编辑

因此,我已经找到一种解决方案。但是,最好对内置Icon()函数进行自己的扩展/重载,但是我不确定是否有适当的方法来实现此功能。

3 个答案:

答案 0 :(得分:2)

原来,我没有动脑筋。答案很简单。

要点是Icon() 一个可组合的函数,这意味着当然可以在其中使用 vectorResource()

因此,正确的方法不是秘密……要创建自己的MyAppIcon()组件,调用vectorResource(),然后返回正常的Icon(),就像这样:

正确的方式

@Composable
fun MyAppIcon(
    resourceId: Int,
    modifier: Modifier = Modifier,
    tint: Color = AmbientContentColor.current
) {
    Icon(
        asset = vectorResource(id = resourceId),
        modifier = modifier,
        tint = tint
    )
}

然后您可以在其他地方创建对象,如下所示:

object MyAppIcons {
    val SomeIcon = R.drawable.someIcon
    val AnotherIcon = R.drawable.anotherIcon
}

将两者放在一起时,可以像这样使用它:

MyAppIcon(MyAppIcons.SomeIcon)

我希望Google尽快添加此替代项,以便我们传递资源ID。

答案 1 :(得分:1)

有一种方法可以使用Icon(Icons.Default.Plus)加载资产。您需要建立一个灭绝属性

val androidx.compose.material.icons.Icons.Filled.FiveG : VectorAsset
    get() {

    }

但是我看不出将VectorAsset置于可组合函数之外的方法。 当然你可以做这样的事情

val androidx.compose.material.icons.Icons.Filled.FiveG : VectorAsset
    get() {
        return Assets.FiveG
    }

object Assets {
    lateinit var FiveG: VectorAsset
}

@Composable
fun initializeAssets() {
    Assets.FiveG = vectorResource(R.drawable.ic_baseline_5g_24)
}

但是具有副作用的可组合药物是一个坏主意。因此,我正在等待有人找到一种方法,将SVG转换为VectorAsset Kotlin类或在可组合函数之外获取VectorAsset对象。

答案 2 :(得分:0)

来自Resources in Compose

使用 painterResource API 加载矢量可绘制对象或光栅化资产格式(如 PNG)。您不需要知道可绘制对象的类型,只需在 painterResource 组合项或 Image 修饰符中使用 paint

// Files in res/drawable folders. For example:
// - res/drawable-nodpi/ic_logo.xml
// - res/drawable-xxhdpi/ic_logo.png

// In your Compose code
Icon(
    painter = painterResource(id = R.drawable.ic_logo),
    contentDescription = null // decorative element
)