Markwon插件Drawable tint主题切换失效:ApplicationContext问题排查
我在Markwon库中开发插件,实现通过Markdown语法加载应用内资源图片。目前图片能正常加载,但tintColor不生效,深色主题下图片几乎看不见。我尝试用android.R.attr.colorControlNormal设置Drawable的tintColor,首次启动时正常,但切换主题后颜色不更新;而同样的Drawable直接用在布局(比如工具栏)里时,tint能随主题正常切换。
更新1
问题根源出在context:用Hilt提供的@ApplicationContext创建Markwon实例时,tintColor异常;但在Fragment里本地创建Markwon实例,tintColor就能正常随主题切换。
val tintColor = MaterialColors.getColor(context, android.R.attr.colorControlNormal, Color.RED)


现有代码
DrawableSchemeHandler实现
// 参考Markwon图片自定义SchemeHandler文档 class DrawableImagesConfigure(private val context: Context) : ImagesPlugin.ImagesConfigure { override fun configureImages(plugin: ImagesPlugin) { plugin.addSchemeHandler(schemeHandler) } private val schemeHandler = object : SchemeHandler() { @SuppressLint("DiscouragedApi") // 处理`drawable://ic_account_24dp_white`这类URL override fun handle(raw: String, uri: Uri): ImageItem { val drawableName = raw.substring("drawable://".length) val drawableId = context.resources.getIdentifier(drawableName, "drawable", context.packageName) // 允许抛出异常,async-image-loader会捕获 val drawable: Drawable = AppCompatResources.getDrawable(context, drawableId) ?: throw Exception("ID为$drawableId的Drawable不存在") // 每次获取的颜色值都一样,不随主题变化 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") } } }
矢量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>
使用与主题绑定的Context
ApplicationContext是全局上下文,不随Activity/Fragment的主题变化而更新,所以获取的属性值始终是应用启动时的主题颜色。需要改用Activity或Fragment的Context来创建Markwon实例和处理Drawable加载。
如果用Hilt注入,不要直接注入@ApplicationContext,而是在Activity/Fragment中注入@ActivityContext或直接使用requireContext()(Fragment中)。使用TintList而非固定颜色值
不要用setTint()设置单一颜色,而是用setTintList()绑定属性值,让Drawable自动跟随主题变化:
// 替换原有的setTint代码 val tintList = ContextCompat.getColorStateList(context, android.R.attr.colorControlNormal) drawable.setTintList(tintList)
这样Drawable会根据当前上下文的主题自动更新tint颜色,即使主题切换也能同步变化。
- 避免提前缓存Drawable
Markwon的SchemeHandler如果缓存了Drawable实例,主题切换时不会重新加载,所以要确保每次处理请求时都重新获取Drawable并设置tintList,或者监听主题变化事件触发Markwon重新渲染内容。
内容的提问来源于stack exchange,提问作者Viewed

