如何根据属性名称和当前主题获取颜色?

问题描述 投票:0回答:1

Markwon 库中,我想添加一个插件,如果以 Markdown 格式写入

![alt text](drawable://icon_name)
,它将显示应用程序资源中的图像。

下面的代码有效。但

tintColor
不适用于图像。因此,它在深色主题中不可见。因此,我添加了
android.R.attr.colorControlNormal
资源的值来更改可绘制对象的
tintColor
。显然 Markwon 删除了这个值(它位于可绘制文件的标记中,格式为
"?attr/colorControlNormal"

它起作用了。但切换到深色主题时颜色不会改变。

android.R.attr.colorControlNormal
属性的值与白色主题相同。可能是什么错误?

当这个drawable直接用在工具栏或其他地方的标记中时,

tintColor
会根据主题而改变。

更新1

context
的问题。当 Hilt 提供
markwon
@ApplicationContext
实例时,
tintColor
不正确。如果在片段中本地创建
markwon
的实例,则
tintColor
将是正确的。

val tintColor = MaterialColors.getColor(context, android.R.attr.colorControlNormal, Color.RED)

enter image description here

enter image description here

// https://noties.io/Markwon/docs/v4/image/#custom-schemehandler
class DrawableImagesConfigure(private val context: Context) : ImagesPlugin.ImagesConfigure {

    override fun configureImages(plugin: ImagesPlugin) {
        plugin.addSchemeHandler(schemeHandler)
    }

    private val schemeHandler = object : SchemeHandler() {
        @SuppressLint("DiscouragedApi")
        // will handle URLs like `drawable://ic_account_24dp_white`
        override fun handle(raw: String, uri: Uri): ImageItem {
            val drawableName = raw.substring("drawable://".length)
            val drawableId = context.resources.getIdentifier(drawableName, "drawable", context.packageName)

            // it's fine if it throws, async-image-loader will catch exception
            val drawable: Drawable = AppCompatResources.getDrawable(context, drawableId)
                ?: throw Exception("The drawable with drawableId $drawableId does not exist")

            // every time the same value
            val tintColor = MaterialColors.getColor(context, android.R.attr.colorControlNormal, Color.RED)
            drawable.setTint(tintColor)
            return ImageItem.withResult(drawable)
        }

        override fun supportedSchemes(): Collection<String> {
            return setOf("drawable")
        }
    }
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:tint="?attr/colorControlNormal"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M4,15h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,13c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM4,19h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,17c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM4,11h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,9c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM3,6c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,5c-0.55,0 -1,0.45 -1,1z" />
</vector>
android kotlin android-drawable android-theme
1个回答
0
投票
// Fragment
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    DrawableImagesConfigure.updateTintColor(requireContext())
}
class DrawableImagesConfigure(@ApplicationContext private val context: Context) : ImagesPlugin.ImagesConfigure {

    private val schemeHandler = object : SchemeHandler() {
        override fun handle(raw: String, uri: Uri): ImageItem {
            // ...
            DrawableCompat.setTint(drawable, tintColorState.value)
            // ...
        }

        // ...
    }

    companion object {
        private val tintColorState = MutableStateFlow(Color.RED)

        fun updateTintColor(context: Context) {
            tintColorState.value = MaterialColors.getColor(context, android.R.attr.colorControlNormal, Color.RED)
        }
    }
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.