ThemeFramework 主题切换框架实现

前言

做了一个主题切换框架,在这里毛遂自荐一下,小伙伴们看看有没有用,欢迎批评指正。

项目地址:https://github.com/l0neman/ThemeFramework

下面是项目的 README.md 自述文件。

ThemeFramework

Android 即时主题切换框架

核心是基于属性(attrs.xml 中配置)可根据所属主题(themes.xml 中配置)的不同,获得每种主题下的对应资源。

使用形式是在布局中配置对应的主题属性,然后一行代码一键切换主题。

1.gif

2.gif

PS:

欢迎小伙伴们提出建议和贡献代码。

主要特点

  1. 低侵入性,不提供强制使用的控件

只提供主题属性以供布局中配置,可通过正则表达式搜索然后批量移除,不移除也不会对程序逻辑造成任何影响。

  1. 高扩展性,易于支持新的 View

只需提供自定义主题属性和将属性资源设置给 View 的逻辑,以框架开发者和框架使用者的角度对支持的 View 类型进行扩展均非常方便。

要求:

必须使用 androidx 提供的 AppCompatActivityFragment(几乎是 Android 开发必选项),因为它们都是 LifecycleOwner 的实现类,框架可以方便的监听组件的生命周期,便于在组件销毁时自动释放资源,避免使用者手动处理资源。

待优化:

  1. 提供的主题属性 Android Studio 不会自动提示,目前主题属性的命名是在对应 View 的原始属性之前添加 tf_ 前缀,所以较易书写;
  2. 主题属性在 Android Framework 提供的原生控件标签中会报红,因为 Android Studio 认为主题属性并非控件本身属性,虽然不影响编译,但是会令人不舒服。例如:
<Button
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?attr/selectableItemBackground"
  android:textColor="?attr/appTextColor"
  app:tf_background="selectableItemBackground"
  app:tf_textColor="appTextColor" />
  <!-- 最后两行 IDE 会显示红色 -->

建议解决办法:

  1. 使用相应的 androidx.appcompat.widget.AppCompatXXX 组件替代,就不会报红了,因为 Android Studio 认为 androidx Android Studio 允许使用未知属性。目前几乎所有的控件都有对应的 androidx 兼容性组件,除了 ListView、ProgressBar 零星组件;
<androidx.appcompat.widget.AppCompatButton
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?attr/selectableItemBackground"
  android:textColor="?attr/appTextColor"
  app:tf_background="selectableItemBackground"
  app:tf_textColor="appTextColor" />
  1. 或者加入 tools:ignore="MissingPrefix" 属性即可去除警告。
<Button
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="?attr/selectableItemBackground"
  android:textColor="?attr/appTextColor"
  app:tf_background="selectableItemBackground"
  app:tf_textColor="appTextColor" 
  tools:ignore="MissingPrefix" />

快速开始

  1. 定义应用主题和主题属性

首先确定你的应用支持几种主题,例如支持白天主题和夜间主题,那么需要准备这两种主题所需的主题资源,通常是 color 和 drawable 资源。

例如,提供字体颜色和设置图标两个主题资源,那么首先在 attrs.xml 中自定义主题资源属性:

<!-- attrs.xml -->

<!-- 字体颜色,color 类型 -->
<attr name="appTextColor" format="color" />
<!-- 设置图标,drawable 类型 -->
<attr name="ic_settings" format="reference" />

然后在 themes.xml 定义每种主题,以及主题包含的主题资源属性对应的具体资源:

<!-- themes.xml -->

<!-- 父主题 -->
<style name="BaseTheme.Light" parent="Theme.AppCompat.Light.NoActionBar"></style>
<style name="BaseTheme.Dark" parent="Theme.AppCompat.NoActionBar"></style>

<!-- 夜间主题,白色文本和图标 -->
<style name="AppTheme.Black" parent="BaseTheme.Dark">
  <item name="appTextColor">#FFFFFF</item>
  <item name="ic_settings">@drawable/ic_baseline_settings_white_24</item>
</style>

<!-- 白天主题,黑色文本和图标 -->
<style name="AppTheme.White" parent="BaseTheme.Light">
  <item name="appTextColor">#000000</item>
  <item name="ic_settings">@drawable/ic_baseline_settings_black_24</item>
</style>

主题资源准备完毕,下面可以进行主题切换了。

  1. 框架初始化

首先在应用的 Application 类的 onCreate 方法中初始化框架。

通常当应用的用户本次切换主题后,下次打开应用需要保证应用处于用户最后一次切换的主题,初始化就是为了设置用户最后一次的主题,同时保证每个 Activity 创建时都使用了当前的主题。

public class MyApp extends Application {
   
  @Override public void onCreate() {
   
    super.onCreate();
    // R.style.AppTheme 为应用首次启动默认的主题
    ThemeFramework.getInstance().setup(this, R.style.AppTheme);
  }
}
  1. 配置主题属性

下面以 TextView 和 ImageView 为例,实现不同主题下的文字颜色和图标。

在应用的 Activity 的布局中进行如下配置:

<androidx.appcompat.widget.AppCompatTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="?attr/appTextColor"
    app:tf_textColor="appTextColor" />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值