Android 应用换肤功能(白天黑夜主题切换)

有时候使用一些APP的时候发现有一个主题切换的功能,感觉挺好玩的,今天也尝试着做了一下,现在总结换肤经验

1.

/**
 * 换肤接口
 */
public interface ColorUiInterface {
    View getView();

    void setTheme(Resources.Theme themeId);
}
 
2.自定义Reletivelayout控件实现换肤接口
 
public class ColorRelativeLayout extends RelativeLayout implements ColorUiInterface {

    private int attr_background = -1;

    public ColorRelativeLayout(Context context) {
        super(context);
    }

    public ColorRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.attr_background = ViewAttributeUtil.getBackgroundAttibute(attrs);
    }

    public ColorRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.attr_background = ViewAttributeUtil.getBackgroundAttibute(attrs);
    }

    @Override
    public View getView() {
        return this;
    }

    @Override
    public void setTheme(Resources.Theme themeId) {
        if (attr_background != -1) {
            ViewAttributeUtil.applyBackgroundDrawable(this, themeId, attr_background);
        }
    }
}
3.在arrs.xml
<attr name="colorPrimaryCenter" format="color|reference" />
<attr name="colorTextIcon" format="color|reference" />
<attr name="colorPrimaryText" format="color|reference" />
<attr name="colorSecondText" format="color|reference" />
<attr name="colorBackground" format="color|reference" />
<attr name="colorDivider" format="color|reference" />
<attr name="colorBackgroundAccent" format="color|reference" />
<attr name="colorHint" format="color|reference" />

4.在style里面定义想要的样式主题
<!--blueTheme-->
<style name="BlueTheme" parent="AppTheme">
    <item name="colorPrimary">@color/colorBluePrimary</item>
    <item name="colorPrimaryDark">@color/colorBluePrimaryDark</item>
    <item name="colorAccent">@color/colorBluePrimaryDark</item>
    <!--<item name="md_title_color">@color/colorBluePrimary</item>-->
    <!--<item name="md_link_color">@color/colorBluePrimary</item>-->
    <!--<item name="md_positive_color">@color/colorBluePrimary</item>-->

</style>

<!--redTheme-->
<style name="RedTheme" parent="AppTheme">
    <item name="colorPrimary">@color/colorRedPrimary</item>
    <item name="colorPrimaryDark">@color/colorRedPrimaryDark</item>
    <item name="colorAccent">@color/colorRedPrimaryDark</item>
    <!--<item name="md_title_color">@color/colorRedPrimary</item>-->
    <!--<item name="md_link_color">@color/colorRedPrimary</item>-->
    <!--<item name="md_positive_color">@color/colorRedPrimary</item>-->

</style>

5.在Activity中点击按钮弹出对话框(此Activity有两个要求 1.继承
AppCompatActivity 2.实现ColorChooserDialog.ColorCallback
public void onClick(String content) {
    new ColorChooserDialog.Builder(this, R.string.theme)
            .customColors(R.array.colors, null)
            .doneButton(R.string.done)
            .cancelButton(R.string.cancel)
            .allowUserColorInput(false)
            .allowUserColorInputAlpha(false)
            .show();
}

6.
@Override
public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {
    if (selectedColor == ThemeUtils.getThemeColor(this, R.attr.colorPrimary))
        return;
    EventBus.getDefault().post(new SkinChangeEvent());

    if (selectedColor == getResources().getColor(R.color.colorBluePrimary)) {
        setTheme(R.style.BlueTheme);
        PreUtils.setCurrentTheme(this, Theme.Blue);

    } else if (selectedColor == getResources().getColor(R.color.colorRedPrimary)) {
        setTheme(R.style.RedTheme);
        PreUtils.setCurrentTheme(this, Theme.Red);

    } 
}
7.以上更改的是状态栏的主题,修改标题栏样式是这样的
<com.zcy.ghost.ghost.app.theme.ColorRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="68dp"
    android:background="?attr/colorPrimary">

    <TextView
        android:id="@+id/title_name"
        style="@style/title_tv_style"
        android:layout_width="match_parent"
        android:layout_marginTop="20dp" />
</com.zcy.ghost.ghost.app.theme.ColorRelativeLayout>
8.通过调用
ColorUiUtil.changeTheme(rootView, getTheme());

public static void changeTheme(View rootView, Resources.Theme theme) {
    if (rootView instanceof ColorUiInterface) {
        ((ColorUiInterface) rootView).setTheme(theme);
        if (rootView instanceof ViewGroup) {
            int count = ((ViewGroup) rootView).getChildCount();
            for (int i = 0; i < count; i++) {
                changeTheme(((ViewGroup) rootView).getChildAt(i), theme);
            }
        }
}
来通知标题栏回调然后更新background

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序邦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值