非常感谢http://www.androidengineer.com/2010/06/using-themes-in-android-applications.html对他的工作提示.
但现在让我们说我希望得到一个有点可爱的应用程序,不仅改变颜色和drawables,但我也想改变字符串.例如,我可能想要添加一个盗版主题,然后“提交”将是“Arrrrgh!”
所以,我的基本问题是:如何通过用户可选择的主题更改我的应用程序中的字符串?
编辑:
做到这一点:该应用程序有12个按钮和32个文本视图我想要主题依赖,我想在没有巨型映射或大量定制attrs的情况下完成此操作.
所有3种当前解决方案都可以使用.寻找更干净的东西虽然我不知道这样的野兽存在.
Let’s say I have an application with 2 themes: masculine and feminine. The themes simply change out the color palette and a few drawables to appeal to the user’s preferred tastes.
我们假装你在做别的事情怎么样?这是一种设计反模式,基于性别关联特定颜色(例如,“像粉红色的女孩”).
这并不是说你的技术目标是坏的,只是这是一个真正的陈规定型的例子.
For instance,I might want to add a pirate theme and then “Submit” would be “Arrrrgh!”
仅当“取消”映射到“Avast!”时.
How can I change the strings throughout my app via user selectable themes?
你还没有说过这些字符串的来源.他们是字符串资源吗?数据库条目?您是从Web服务检索的?别的什么?
我现在假设这些是字符串资源.根据定义,您需要拥有N个字符串副本,每个主题一个.
由于性别和盗版状态不是Android作为可能的资源集限定符跟踪的事物,因此您不能将这些字符串资源放在不同的资源集中.虽然它们可以位于不同的文件中(例如,res / values / strings_theme1.xml),但文件名不是字符串的资源标识符的一部分.因此,您将不得不使用某种前缀/后缀来跟踪哪些字符串属于哪些主题(例如,@ string / btn_submit_theme1).
如果这些字符串在运行时没有变化 – 它只是布局资源中的任何内容 – 您可以从Chris Jenkins’ Calligraphy library获取一个页面.他有自己的LayoutInflater子类,用于重载某些标准XML属性.在他的情况下,他的重点是android:fontFamily,他支持映射到资产中的字体文件.
在你的情况下,你可以重载android:文本.在你的布局文件中,而不是它指向你的任何实际字符串,你可以让它成为你想要的字符串资源的基本名称,没有任何主题标识符(例如,如果真正的字符串是@ string / btn_submit_theme1和亲属,你可以有android:text =“btn_submit”).您的LayoutInflater子类将获取该值,附加主题名称后缀,在您的资源上使用getIdentifier()来查找实际的字符串资源ID,并从那里获取与您的主题相关联的字符串.
对此的一个变体是将基本名称放在android:标签而不是android:text. android:text可能指向你真正的字符串资源之一,以帮助GUI设计等.您的LayoutInflater将获取标记并使用它在运行时派生正确的字符串.
如果要将文本替换为从基于主题的字符串资源中提取的其他文本,则可以将get-the-string-given-base-name逻辑隔离到可以应用的某个静态实用程序方法中.
虽然最初获得此权限需要一些工作,但就受影响的UI小部件和字符串的数量而言,它将扩展到任意复杂性.您仍然需要记住为您定义的任何新字符串添加所有主题的值(创建自定义Lint检查的奖励点或用于验证此项的Gradle任务).