【发布时间】:2019-07-04 18:22:29
【问题描述】:
各位 Android 开发者您好,我需要澄清一个关于 Android 应用程序中动态资源管理的疑问。
我需要我的应用程序根据手机上配置的语言使用后端返回的翻译。
我想以优雅的方式在自定义 LayoutInflater 上实现它,该自定义 LayoutInflater 根据图形组件的类型应用 ViewTransformer。
每个 ViewTransformer 只会收集标识符(例如@id/landing_welcome_text)并进行下一次调用:
val value = attrs.getAttributeValue(index)
if (value != null && value.startsWith("@")) {
val text = view.context.resources.getString(attrs.getAttributeResourceValue(index, 0))
setTextForView(view, text)
}
一个 ContextWrapper 已经实现,它返回我的自定义 LayoutInflater 和一个 Resource 实现
override fun getSystemService(name: String): Any {
return if (Context.LAYOUT_INFLATER_SERVICE == name)
CustomLayoutInflater(
LayoutInflater.from(baseContext),
this,
viewTransformerManager
)
else
super.getSystemService(name)
}
override fun getResources(): Resources = customResources
问题在于,覆盖 Resources 类的行为被认为是不推荐使用的策略。
正如文档所说:
此构造函数已弃用。资源不应该由 应用。请参阅 Context.createConfigurationContext(Configuration)。
class CustomResourcesWrapper constructor(
res: Resources,
private val languageStringRepo: ILanguageStringRepo
): Resources(res.assets, res.displayMetrics, res.configuration) {
@Throws(Resources.NotFoundException::class)
override fun getString(id: Int): String {
val value = getStringFromRepository(id)
return value ?: super.getString(id)
}
}
有谁知道我如何在不覆盖 Resources 类的情况下获得相同的功能?
非常感谢您的帮助:)
【问题讨论】:
-
为什么不让您的
ViewModel为您的活动/片段提供正确的字符串,就像您使用任何其他动态数据一样填充它们?鉴于涉及服务器,无论如何您都需要考虑网络+磁盘 I/O 和线程,这与您对服务器的任何其他操作没有什么不同。 -
感谢您的回答,这个策略在我看来更加自动化,并且被封装在膨胀视图的过程中,我不希望在我的功能的所有视图模型中看到翻译的逻辑。我将翻译加载到内存中的 LRU 缓存中,可以立即访问。
-
我不确定如何使用 ViewModel 执行此操作,在我加载翻译之前,屏幕可能没有文字显示
标签: android android-layout android-view android-resources layout-inflater