文章

动态换肤功能

动态换肤功能

动态换肤功能

1、方案一:使用主题文件

  1. 定义换肤资源
1
2
3
4
5
6
7
8
9
10
11
12
13
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <item name="theme_main_color">@color/purple_500</item>
        <item name="theme_sub_color">@color/purple_200</item>
        <item name="theme_main_bg">@mipmap/bg1</item>
    </style>

    <style name="Theme.Style1" parent="Theme.Default">
        <item name="theme_main_color">@color/purple_500</item>
        <item name="theme_sub_color">@color/teal_200</item>
        <item name="theme_main_bg">@mipmap/bg2</item>
    </style>
</resources>
  1. 应用主题
1
2
3
4
5
6
7
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if ("default" != getSp(this, "theme")) {
        setTheme(R.style.Theme_Style1)
    }
    setContentView(R.layout.activity_demo1_theme)
}
  1. 重启 Activity
1
2
3
4
5
6
7
8
9
fun onChangeTheme2(view: View) {
    toggleTheme()
    val intent = intent
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
    finish()
    overridePendingTransition(0, 0) //不设置进入退出动画
    startActivity(intent)
    overridePendingTransition(0, 0) //不设置进入退出动画
}

缺点

  1. 需要定义很多套主题资源,占用 apk 体积
  2. 需要重新创建 Activity

2、方案二:LayoutInflater#setFactory2

1、收集需要换肤的控件以及属性
2、制作皮肤包
3、读取皮肤包
4、动态刷新控件
5、其他:支持手动设置属性,手动添加控件

方案特点:

  1. 自动化程度比较高,改造成本也低。
  2. 存在一定侵入性。

3、方案三:使用 tag 标记需要换肤的属性

  1. 在 xml 标记要换肤的属性
  2. 换肤的时候遍历视图树,然后换肤
本文由作者按照 CC BY 4.0 进行授权