【问题标题】:Jetpack Compose: Custom VectorAsset Icon object similar to built-in `Icons.Default`Jetpack Compose:自定义 VectorAsset 图标对象,类似于内置的 `Icons.Default`
【发布时间】:2020-11-05 15:20:34
【问题描述】:

看起来从res文件夹中的Android矢量资源加载自定义图标的唯一方法是在@Composable函数中使用vectorResource(R.drawable.myVectorName)方法。

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

看起来vectorResource() 方法使用了一个名为loadVectorResource()internal 方法,它用来读取构成矢量资产文件的实际XML 文件的方法也是内部的。

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

编辑

所以,我已经找到了一个解决方案。但是,我最好自己扩展/重载内置 Icon() 函数,但我不确定是否有合适的方法来做到这一点。

【问题讨论】:

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


    【解决方案1】:

    原来我没有使用我的大脑。答案很简单。

    要点是,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。

    【讨论】:

      【解决方案2】:

      来自Resources in Compose

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

      // 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
      )
      

      【讨论】:

        【解决方案3】:

        有一种使用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 对象的方法。

        【讨论】:

          猜你喜欢
          • 2021-12-17
          • 1970-01-01
          • 2020-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-13
          相关资源
          最近更新 更多