如果在网上搜换肤,方案五花八门,但是根据app的需求,以及无设计师的情况下,基本上简约风格app,这种风格下只需要几个颜色就行了,根本不需要动态从磁盘加载皮肤apk,而且通过反射操作侵入性太强,因此attr大法才是最适合目前的我所做的app实现。
网上的换肤方法侵入性太强,而纯色app不需要各种花式的皮肤,基本上2三套颜色就行了,主色,次色,而其他则非黑即白。深色模式实现就更简单了,用着色tint就实现了。
经过了几天的研究发现,动态修改setTheme
是有bug的, bug就是状态栏颜色和actionbar在未在activity定义attr背景的情况下实现修改actionbar的就有这个bug,2015年在stackoverflow网站上就有人提出解决方法,这个解决方法是没有办法的方法,需要在baseactivity进行判断,如果有actionbar就设置actionbar颜色,
以及设置状态栏颜色。
达到的效果
在颜色选择器中是可以直接使用实现的属性?attr
而在drawable,则需要包裹一层drawable引用color,直接使用color
属性也是会报错的,
正常的按钮,对话框,控件不需要再通过代码,xml设置颜色,
而网上的操作性太麻烦,正规的写法就是官方的写法,能不在view xml定义的就不在view xml定义
这样侵入性比较小。
颜色主题需要注意的事项
drawable要使用颜色属性只能包裹一层shape
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/defaultThemeColorSecond"/>
</shape>
第三方自定义ui 有的是只支持颜色不支持attr的。则需要进行额外适配处理,
其处理方式就是根据属性查找对应的颜色 或者id (colorres)
颜色属性找颜色
public static int attrFetchColor(Context context,int attrColor) {
int[] attribute = new int[]{attrColor};
TypedArray array =context.getTheme().obtainStyledAttributes(attribute);
int color = array.getColor(0, AppContext.getInstance().getResources().getColor(R.color.themeColor));
array.recycle();
return color;
}
查找id
public static int attrFetchColorId(Context context,int attrColor) {
int[] attribute = new int[]{attrColor};
TypedArray array = context.obtainStyledAttributes(attribute);
int colorID = array.getResourceId(0, R.color.themeColor);
array.recycle();
return colorID;
}
在baseactivity onCreate中修改状态栏颜色
public static void updateActionBarAndStatusColor(Activity activity) {
if (activity instanceof AppCompatActivity) {
AppCompatActivity appCompatActivity = (AppCompatActivity) activity;
ActionBar supportActionBar = appCompatActivity.getSupportActionBar();
if (supportActionBar != null) {
int i = AppUtils.attrFetchColor(activity,R.attr.defaultThemeColor);
supportActionBar.setBackgroundDrawable(new ColorDrawable(i));
}
}
android.app.ActionBar actionBar = activity.getActionBar();
if (actionBar != null) {
int color = AppUtils.attrFetchColor(activity,R.attr.defaultThemeColor);
actionBar.setBackgroundDrawable(new ColorDrawable(color));
}
if (Build.VERSION.SDK_INT >= 21) {
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
int statusBarBackground = AppUtils.attrFetchColor(activity,R.attr.colorPrimaryDark);
Window window = activity.getWindow();
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// window.setStatusBarColor(backgroundColor);
window.setStatusBarColor(statusBarBackground);
}
}
主题修改代码
getBinding().rlMyThemeSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
int currentMode = NightModeUtils.Companion.getSpfThemeMode(AppContext.getInstance());
ThemeMode[] values = ThemeMode.values();
CharSequence[] items=new CharSequence[values.length];
for (int i = 0; i < values.length; i++) {
String title = AppContext.getInstance().getString(values[i].getStringValueId());
items[i]=title;
}
builder.setSingleChoiceItems(items, currentMode, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != currentMode) {
dialog.dismiss();
ThemeMode value = values[which];
NightModeUtils.getInstance(AppContext.getInstance()).setThemeMode(value);
EventBus.getDefault().post(new ThemeChangeEvent().themeChange());
}
}
});
builder.setTitle(AppContext.getStr(R.string.deep_color_theme_setting));
builder.show();
}
});
收到事件进行recreate();
,我这里是在mainact,mainact可直接recreate
,无需finish
适配起来挺快的,通过各种批量替换
但是需要注意的是,第三方对颜色适配做的很烂,哪怕大家众所周知的smartrefresh也不支持属性引用颜色。 因此主要的适配就是处理第三方框架的问题,
这个适配工作基本上一天就搞定了。
另外花的实际是纠结研究为啥actionbar和状态栏颜色通过setTheme无效花费了很多时间,在attach里面替换,以及研究theme的各种方法,以及引用再引用的方式也解决不了问题,
最后既然无效我只能另外走方法了,强制设置。
attr.xml定义
<attr name="defaultThemeColor" format="reference|color"></attr>
<attr name="defaultThemeColorSecond" format="reference|color"></attr>
其实现在每一个主题都实现了,
下面附上theme.xml 仔细看 都实现了defaultThemeColor defaultThemeColorSecond 属性,
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.MyApplication.Blue" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorBlue</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondBlue</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorBlue</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorBlue</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkBlue</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantBlue</item>
<item name="colorOnPrimary">@color/colorOnPrimaryBlue</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorAccent">@color/colorAccentBlue</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="lollipop"> @color/colorPrimaryDarkBlue</item>
<item name="statusBarBackground">@color/colorPrimaryDarkBlue</item>
</style>
<style name="Theme.MyApplication.Yellow" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorYellow</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondYellow</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorYellow</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorYellow</item>
<item name="colorAccent">@color/colorAccentYellow</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkYellow</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantYellow</item>
<item name="colorOnPrimary">@color/colorOnPrimaryYellow</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/colorPrimaryVariantYellow</item>
<item name="controlBackground">@color/colorPrimaryDarkYellow</item>
<item name="statusBarBackground">@color/colorPrimaryDarkYellow</item>
</style>
<style name="Theme.MyApplication.GREEN" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorGreen</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondGreen</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorGreen</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorGreen</item>
<item name="colorAccent">@color/colorAccentGreen</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkGreen</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantGreen</item>
<item name="colorOnPrimary">@color/colorOnPrimaryGreen</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="lollipop">@color/colorPrimaryDarkGreen </item>
<item name="statusBarBackground">@color/colorPrimaryDarkGreen </item>
</style>
<style name="Theme.MyApplication.PURPLE" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorPurple</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondPurple</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorPurple</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorPurple</item>
<item name="colorAccent">@color/colorAccentPurple</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkPurple</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantPurple</item>
<item name="colorOnPrimary">@color/colorOnPrimaryPurple</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorPurple</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkPurple</item>
</style>
<style name="Theme.MyApplication.Amber" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorAmber</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondAmber</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorAmber</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorAmber</item>
<item name="colorAccent">@color/colorAccentAmber</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkAmber</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantAmber</item>
<item name="colorOnPrimary">@color/colorOnPrimaryAmber</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorAmber</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkAmber</item>
</style>
<style name="Theme.MyApplication.Cyan" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorCyan</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondCyan</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorCyan</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorCyan</item>
<item name="colorAccent">@color/colorAccentCyan</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkCyan</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantCyan</item>
<item name="colorOnPrimary">@color/colorOnPrimaryCyan</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorCyan</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkCyan</item>
</style>
<style name="Theme.MyApplication.Brown" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorBrown</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondBrown</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorBrown</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorBrown</item>
<item name="colorAccent">@color/colorAccentBrown</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkBrown</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantBrown</item>
<item name="colorOnPrimary">@color/colorOnPrimaryBrown</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorBrown</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkBrown</item>
</style>
<style name="Theme.MyApplication.Grey" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorGrey</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondGrey</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorGrey</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorGrey</item>
<item name="colorAccent">@color/colorAccentGrey</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkGrey</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantGrey</item>
<item name="colorOnPrimary">@color/colorOnPrimaryGrey</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorGrey</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkGrey</item>
</style>
<style name="Theme.MyApplication.DeepOrange" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorDeepOrange</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondDeepOrange</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorDeepOrange</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorDeepOrange</item>
<item name="colorAccent">@color/colorAccentDeepOrange</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkDeepOrange</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantDeepOrange</item>
<item name="colorOnPrimary">@color/white_no_night</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/colorSecondaryVariantOrange</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="statusBarBackground">@color/themeColorDeepOrange</item>
<item name="android:statusBarColor">@color/colorPrimaryDarkDeepOrange</item>
</style>
<style name="Theme.MyApplication.NotImpl" parent="Theme.AppCompat.DayNight.DarkActionBar">
<item name="defaultThemeColor">@color/themeColor</item>
<item name="defaultThemeColorSecond">@color/themeColorSecond</item>
<item name="colorPrimary">?attr/defaultThemeColorSecond</item>
<item name="colorPrimaryDark">?attr/defaultThemeColor</item>
<item name="colorAccent">?attr/defaultThemeColorSecond</item>
</style>
<style name="Theme.MyApplication.DefaultBlue" parent="Theme.MyApplication.RootTheme">
<!-- Primary brand color. -->
<item name="defaultThemeColor">@color/themeColor</item>
<item name="defaultThemeColorSecond">@color/themeColorSecond</item>
<!-- style设置没效果代码批量设置-->
<item name="colorButtonNormal">?attr/defaultThemeColorSecond</item>
<item name="android:elevation">0dp</item>
<!-- hide shadow-->
<item name="android:windowContentOverlay">@null</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!-- Primary brand color. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariant</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorOnPrimary">@color/colorOnPrimary</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<!-- <item name="android:statusBarColor">@color/colorPrimaryDark</item>-->
<!-- <item name="statusBarBackground">@color/colorPrimaryDark</item>-->
<!-- Customize your theme here. -->
</style>
<style name="Theme.MyApplication.DefaultBlue.Global" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColor</item>
<item name="defaultThemeColorSecond">@color/themeColorSecond</item>
</style>
<style name="Theme.MyApplication.BLACK" parent="Theme.MyApplication.RootTheme">
<item name="defaultThemeColor">@color/themeColorBlack</item>
<item name="defaultThemeColorSecond">@color/themeColorSecondBlack</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Small</item>
<item name="colorButtonNormal">@color/themeColorBlack</item>
<!-- <style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.DarkActionBar">-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/themeColorSecondBlack</item>
<item name="colorPrimaryDark">@color/themeColorSecondBlack</item>
<item name="colorPrimaryVariant">@color/colorPrimaryVariantBlack</item>
<item name="colorOnPrimary">@color/colorOnPrimaryBlack</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/colorSecondary</item>
<!-- <item name="colorSecondary">@color/teal_200</item>-->
<item name="colorSecondaryVariant">@color/themeColorSecondBlack</item>
<item name="colorOnSecondary">@color/colorOnSecondary</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="lollipop"> @color/colorPrimaryVariantBlack</item>
<item name="statusBarBackground">@color/themeColorBlack</item>
</style>
<style name="Theme.MyApplication.BLACK.NoActionBar" parent="Theme.MyApplication.BLACK">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.DefaultBlue.NoActionBar" parent="Theme.MyApplication.DefaultBlue">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Amber.NoActionBar" parent="Theme.MyApplication.Amber">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.GREEN.NoActionBar" parent="Theme.MyApplication.GREEN">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.PURPLE.NoActionBar" parent="Theme.MyApplication.PURPLE">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Grey.NoActionBar" parent="Theme.MyApplication.Grey">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Yellow.NoActionBar" parent="Theme.MyApplication.Yellow">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Blue.NoActionBar" parent="Theme.MyApplication.Blue">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Brown.NoActionBar" parent="Theme.MyApplication.Brown">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.Cyan.NoActionBar" parent="Theme.MyApplication.Cyan">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.MyApplication.DeepOrange.NoActionBar" parent="Theme.MyApplication.DeepOrange">
<item name="windowActionBar">false</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:actionMenuTextColor">@color/white_no_night</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
root.
<style name="Theme.MyApplication.RootTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
</style>
color实现
<color name="themeColor">#5768FE</color>
<color name="printtestcolor">#f2c4c4</color>
<color name="themeColorSecond">#5766FF</color>
<!--
<color name="themeColor" >#1D4C78</color>
<color name="themeColorSecond" >#1F4E7A</color>-->
<!-- http://mcg.mbitson.com/#!?mcgpalette0=%235768fe 根据颜色找出更深的或者更淡淡的颜色-->
<color name="colorPrimary">@color/themeColor</color>
<color name="colorPrimaryDark">#4F60FE</color>
<color name="colorAccent">#536DFE</color>
<color name="colorPrimaryVariant">@color/themeColor</color>
<color name="colorOnPrimary">@color/white</color>
<color name="colorSecondary">@color/light_blue_disable</color>
<color name="colorSecondaryVariant">@color/teal_700</color>
<color name="colorOnSecondary">@color/black</color>
<color name="themeColorPurple">@color/purple_300</color>
<color name="colorAccentPurple">#E040FB</color>
<color name="themeColorSecondPurple">@color/purple_300</color>
<color name="colorPrimaryPurple">@color/purple_300</color>
<color name="colorPrimaryDarkPurple">#7B1FA2</color>
<color name="colorPrimaryVariantPurple">@color/purple_300</color>
<color name="colorOnPrimaryPurple">@color/white</color>
<color name="themeColorYellow">#FF9800</color>
<color name="themeColorSecondYellow">#FF9800</color>
<color name="colorPrimaryYellow">#F57C00</color>
<color name="colorPrimaryDarkYellow">#FF9800</color>
<color name="colorAccentYellow">#FF9800</color>
<color name="colorPrimaryVariantYellow">#FF9800</color>
<color name="colorOnPrimaryYellow">@color/white</color>
<color name="themeColorGreen">@color/green_700</color>
<color name="themeColorSecondGreen">@color/green_700</color>
<color name="colorPrimaryGreen">@color/green_700</color>
<color name="colorPrimaryDarkGreen">#388E3C</color>
<color name="colorAccentGreen">#4CAF50</color>
<color name="colorPrimaryVariantGreen">@color/green_700</color>
<color name="colorOnPrimaryGreen">@color/white</color>
<color name="themeColorBlue">@color/blue_900</color>
<color name="themeColorSecondBlue">@color/blue_900</color>
<color name="colorPrimaryBlue">@color/blue_900</color>
<color name="colorPrimaryDarkBlue">@color/blue_900</color>
<color name="colorAccentBlue">#448AFF</color>
<color name="colorPrimaryVariantBlue">@color/blue_900</color>
<color name="colorOnPrimaryBlue">@color/white</color>
<color name="themeColorBlack">@color/quantum_black_100</color>
<color name="themeColorSecondBlack">@color/quantum_black_100</color>
<color name="colorPrimaryBlack">@color/quantum_black_100</color>
<color name="colorPrimaryAccent">#5D4037</color>
<color name="colorPrimaryVariantBlack">@color/quantum_black_100</color>
<color name="colorOnPrimaryBlack">@color/white</color>
<color name="themeColorBrown" >#795548</color>
<color name="themeColorSecondBrown" >#795548</color>
<color name="colorAccentBrown">#9E9E9E</color>
<color name="colorPrimaryDarkBrown">#5D4037</color>
<color name="colorPrimaryVariantBrown">@color/black_overlay</color>
<color name="colorOnPrimaryBrown">@color/black</color>
<color name="themeColorTeal" >#009688</color>
<color name="themeColorSecondTeal" >#757575</color>
<color name="colorAccentTeal">#00BCD4</color>
<color name="colorPrimaryDarkTeal">#00796B</color>
<color name="colorPrimaryVariantTeal">@color/black_overlay</color>
<color name="colorOnPrimaryTeal">@color/black</color>
<color name="themeColorCyan" >#00BCD4</color>
<color name="themeColorSecondCyan" >#0097A7</color>
<color name="colorAccentCyan">#009688</color>
<color name="colorPrimaryDarkCyan">#0097A7</color>
<color name="colorPrimaryVariantCyan">#B2EBF2</color>
<color name="colorOnPrimaryCyan">#FFFFFF</color>
<color name="themeColorAmber" >#FFC107</color>
<color name="themeColorSecondAmber" >#FFC107</color>
<color name="colorAccentAmber">#FFC107</color>
<color name="colorPrimaryDarkAmber">#FFA000</color>
<color name="colorPrimaryVariantAmber">#212121</color>
<color name="colorOnPrimaryAmber">#212121</color>
<color name="themeColorDeepOrange" >#FF5722</color>
<color name="themeColorSecondDeepOrange" >#FF5722</color>
<color name="colorAccentDeepOrange">#FF4081</color>
<color name="colorPrimaryDarkDeepOrange">#E64A19</color>
<color name="colorPrimaryVariantDeepOrange">#212121</color>
<color name="colorOnPrimaryDeepOrange">#212121</color>
<color name="colorSecondaryVariantOrange">#E64A19</color>
<color name="themeColorGrey" >#607D8B</color>
<color name="themeColorSecondGrey" >#757575</color>
<color name="colorAccentGrey">#9E9E9E</color>
<color name="colorPrimaryDarkGrey">#455A64</color>
<color name="colorPrimaryVariantGrey">@color/black_overlay</color>
<color name="colorOnPrimaryGrey">@color/black</color>
image.png
image.png
深色主题values-night themes.xml
把正常颜色的拷贝过来然后指定颜色就行了,
修改主题的代码 baseactivityonCreate调用在setContentView之前
fun applySetting(context: Context?): Int {
var themeId = 0;
// 检查主题
val themeModeInt = getSpfThemeMode()
val themeMode = ThemeMode.parseOfInt(themeModeInt)
var disableActionBar: Boolean = false;
var actName: String = "";
var needActionBar:Int =-1;
if (context is BaseActivity) {
needActionBar = context.needActionBar()
if( needActionBar == 1) {
disableActionBar = false;
}else if( needActionBar == 0) {
disableActionBar = true;
}
}
actName = context?.javaClass?.simpleName + " ,是否禁用actionBar " + disableActionBar;
if (context is AppCompatActivity) {
if (needActionBar==-1) {
var act: AppCompatActivity = context;
disableActionBar = if(act.supportActionBar!=null) true else true;//act.supportActionBar is WindowDecorActionBar
}
}
Log.w("ThemeStyle", "主题模式 ${themeMode.name} act $actName");
if (themeMode == ThemeMode.BLUE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Blue_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Blue
}
} else if (themeMode == ThemeMode.YELLOW_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Yellow_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Yellow
}
} else if (themeMode == ThemeMode.PURPLE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_PURPLE_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_PURPLE
}
} else if (themeMode == ThemeMode.GREEN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_GREEN_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_GREEN
}
} else if (themeMode == ThemeMode.GREY_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Grey_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_Grey
}
} else if (themeMode == ThemeMode.BROWN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Brown_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Brown
}
} else if (themeMode == ThemeMode.DEEP_ORANGE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_DeepOrange_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_DeepOrange
}
} else if (themeMode == ThemeMode.AMBER_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Amber_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Amber
}
} else if (themeMode == ThemeMode.CYAN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Cyan_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Cyan
}
} else if (themeMode == ThemeMode.BLACK_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_BLACK_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_BLACK;
}
} else {
if (disableActionBar) {//如果appcontext设置actionbar,act manifest.xml没有声明解除actionbar,然后调用setSupportBar则会抛出异常,因此需要处理适配。
themeId = R.style.Theme_MyApplication_DefaultBlue_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_DefaultBlue
}
}
if (themeId != 0) {
context?.setTheme(themeId)
// return themeId;
}
AppCompatDelegate.setDefaultNightMode(
when (themeMode) {
ThemeMode.MODE_ALWAYS_ON -> AppCompatDelegate.MODE_NIGHT_YES
ThemeMode.MODE_ALWAYS_OFF -> AppCompatDelegate.MODE_NIGHT_NO
ThemeMode.MODE_FOLLOW_SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
else -> {
AppCompatDelegate.MODE_NIGHT_NO
}
}
)
return themeId
}
如果不为0,
if (color != 0) {
// getTheme().applyStyle(color, true);
AppUtils.updateActionBarAndStatusColor(this);
}
另外补充一点,按钮这些一般我都没有修改在每一个activity xml设置的,遵循material design以及theme的写法,全局就可以进行操作的,在<item name="colorPrimary">
就完成了适配,
主要的适配工作还是处理selector的颜色以及第三方框架引用了颜色的情况,另外处理深色兼容的适配。
另外关于重启生效的事情,recreate也是只能修改部分颜色而在我自己曾经写的一款app没有这样的问题,经过比较发现,我的那个app没有一个app是额外指定了主题的,所以状态栏颜色等都能自动马上生效,而且不需要通过代码修改状态栏颜色,因此这个bug是act的xml定义的主题和代码设置的主题冲突bug.
关于This Activity already has an action bar supplie
This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
at androidx.appcompat.app.AppCompatDelegateImpl.setSupportActionBar(Ap
如果在actionbar已经在xml中指定的情况(如果act没有指定则从application节点继承),在代码里面继续设置是会报错的,可在setContentView代码之前调用setTheme指定不包含actionbar的解除actionbar
则调用setSupportActionBar
不会抛出已设置的错误。
setSupportActionBar的作用是把布局xml中的toolbar 依附到act中。
关于状态栏通过setTheme recreate有些东西不生效 ,重启不生效的原因 最根本原因是使用了MaterialComponents 主题而不是Theme.AppCompat,但是不使用MaterialComponents主题会导致google的组件样式无法全局生效,这是个矛盾,而且导致我的app大量崩溃,都是因为google的组件问题。
然后我继续找问题,还是改成了MaterialComponents主题,发现recreate又没有bug了,可以不重启全部更新。 之前又不行,我搞的精神崩溃了,也许是编译缓存问题??。。
总之最后通过recreate可以实现当前界面更新状态栏,不过第二个界面则不行,需要代码设置。不过体验比之前好了,不需要彻底重启app,由于保存了状态,基本上切换主题就感觉没有重启act的感觉,实际上是重建了的。
最后的最后我发现深色切换 回来或者切换过去,会导致很多地方不生效,比如状态栏,部分背景,
在recreate执行之前重新设置一遍主题可以解决此问题
if (which != currentMode) {
dialog.dismiss();
ThemeMode value = values[which];
NightModeUtils.getInstance(AppContext.getInstance()).setThemeMode(value);
if (currentMode == 0 || which == 0) {//如果是从深色切换过来的就需要先执行setTheme,也就是执行了2次。
NightModeUtils.getInstance(getContext()).applySetting(getContext());
getActivity().recreate();
} else {
EventBus.getDefault().post(new ThemeChangeEvent().themeChange());
}
}
最后的最后是这样的
ThemeMode value = values[which];
NightModeUtils.getInstance(AppContext.getInstance()).setThemeMode(value);
if (currentMode == 0 || which == 0) {
//call setTheme
NightModeUtils.getInstance(getContext()).applySetting(getContext());
//如果重启会发现部分没生效,深色模式的切换是不需要重启就能生效的
} else {
getActivity().recreate();
}
完整代码
import android.app.Activity
import android.content.Context
import android.content.res.TypedArray
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import com.sotrun.app.R
import com.sotrun.app.base.BaseActivity
import com.sotrun.app.utils.DateUtils
import java.io.Serializable
import java.util.*
open class NightModeUtils constructor(context: Context) {
private val mSpf =
context.applicationContext.getSharedPreferences(SP_THEME_NAME, Context.MODE_PRIVATE)
companion object {
@Volatile
private var INSTANCE: NightModeUtils? = null
fun getSpfThemeMode(context: Context): Int =
context.getSharedPreferences(SP_THEME_NAME, Context.MODE_PRIVATE)
.getInt(SPF_THEME_MODE, ThemeMode.MODE_FOLLOW_SYSTEM.intValue)
@JvmStatic
fun getInstance(context: Context): NightModeUtils =
INSTANCE ?: synchronized(this) {
INSTANCE ?: NightModeUtils(context).also {
INSTANCE = it
}
}
private const val SPF_THEME_MODE = "theme_mode"
private const val SP_THEME_NAME = "config_data"
private const val SPF_THEME_TIMER = "theme_timer"
}
/** 获取设置 */
private fun getSpfThemeMode(): Int =
mSpf.getInt(SPF_THEME_MODE, ThemeMode.MODE_FOLLOW_SYSTEM.intValue)
/** 设置 */
private fun setSpfThemeMode(mode: Int) {
/*
注意,当两个编辑器同时修改首选项时
*时间,最后一个调用commit的人获胜。
*
*/
mSpf.edit().putInt(SPF_THEME_MODE, mode).commit()
}
/** 获取时间设置 */
private fun getSpfThemeTimer(): String = mSpf.getString(SPF_THEME_TIMER, null) ?: "18:00~08:00"
/** 设置时间 */
private fun saveSpfThemeTimer(timer: String) {
mSpf.edit().putString(SPF_THEME_TIMER, timer).apply()
}
/** 获取设置好的ThemeMode */
fun getThemeMode(): ThemeMode = ThemeMode.parseOfInt(getSpfThemeMode())
/** 设置模式 */
fun setThemeMode(mode: ThemeMode) {
setSpfThemeMode(mode.intValue)
}
/** 获取设置好的定时时间 */
fun getThemeTime(): ThemeTime {
val timeStr = getSpfThemeTimer()
return ThemeTime(
beginHour = timeStr.split("~")[0].split(":")[0].toInt(),
beginMinute = timeStr.split("~")[0].split(":")[1].toInt(),
endHour = timeStr.split("~")[1].split(":")[0].toInt(),
endMinute = timeStr.split("~")[1].split(":")[1].toInt()
)
}
/** 设置定时时间 */
fun setThemeTime(time: ThemeTime) {
saveSpfThemeTimer(time.toTimerString())
}
/**
* 应用存储的设置
*/
fun applySetting() {
applySetting(null);
}
fun applySetting(context: Context?): Int {
var themeId = 0;
// 检查主题
val themeModeInt = getSpfThemeMode()
val themeMode = ThemeMode.parseOfInt(themeModeInt)
var disableActionBar: Boolean = false;
var actName: String = "";
var needActionBar:Int =-1;
if (context is BaseActivity) {
needActionBar = context.needActionBar()
if( needActionBar == 1) {
disableActionBar = false;
}else if( needActionBar == 0) {
disableActionBar = true;
}
}
actName = context?.javaClass?.simpleName + " ,是否禁用actionBar " + disableActionBar;
if (context is AppCompatActivity) {
if (needActionBar==-1) {
var act: AppCompatActivity = context;
val a: TypedArray = act.obtainStyledAttributes(R.styleable.AppCompatTheme)
val needActionBar = a.getBoolean(R.styleable.AppCompatTheme_windowActionBar, false)
disableActionBar = !needActionBar
// disableActionBar = if(act.supportActionBar!=null) true else true;//act.supportActionBar is WindowDecorActionBar
}
}
Log.w("ThemeStyle", "主题模式 ${themeMode.name} act $actName");
if (themeMode == ThemeMode.BLUE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Blue_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Blue
}
} else if (themeMode == ThemeMode.YELLOW_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Yellow_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Yellow
}
} else if (themeMode == ThemeMode.PURPLE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_PURPLE_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_PURPLE
}
} else if (themeMode == ThemeMode.GREEN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_GREEN_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_GREEN
}
} else if (themeMode == ThemeMode.GREY_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Grey_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_Grey
}
} else if (themeMode == ThemeMode.BROWN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Brown_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Brown
}
} else if (themeMode == ThemeMode.DEEP_ORANGE_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_DeepOrange_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_DeepOrange
}
} else if (themeMode == ThemeMode.AMBER_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Amber_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Amber
}
} else if (themeMode == ThemeMode.CYAN_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_Cyan_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_Cyan
}
} else if (themeMode == ThemeMode.BLACK_THEME) {
if (disableActionBar) {
themeId = R.style.Theme_MyApplication_BLACK_NoActionBar;
} else {
themeId = R.style.Theme_MyApplication_BLACK;
}
} else {
if (disableActionBar) {//如果appcontext设置actionbar,act manifest.xml没有声明解除actionbar,然后调用setSupportBar则会抛出异常,因此需要处理适配。
themeId = R.style.Theme_MyApplication_DefaultBlue_NoActionBar
} else {
themeId = R.style.Theme_MyApplication_DefaultBlue
}
}
if (themeId != 0) {
if(context is Activity){
context?.setTheme(themeId)
}else{
// context?.theme?.applyStyle(themeId, true)
}
// return themeId;
}
AppCompatDelegate.setDefaultNightMode(
when (themeMode) {
ThemeMode.MODE_ALWAYS_ON -> AppCompatDelegate.MODE_NIGHT_YES
ThemeMode.MODE_ALWAYS_OFF -> AppCompatDelegate.MODE_NIGHT_NO
ThemeMode.MODE_FOLLOW_SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
else -> {
AppCompatDelegate.MODE_NIGHT_NO
}
}
)
return themeId
}
/**
* 定时开启
*/
private fun clock(): Int {
val time = getThemeTime()
val startTime = time.startTime.replace(":", ".").toFloat()
val stopTime = time.stopTime.replace(":", ".").toFloat()
val curTime = DateUtils.getFormatDate("HH.mm", Date()).toFloat()
return if (stopTime > startTime) {
// 结束时间和开始时间都在同一天
if (curTime > startTime && curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
} else {
// 结束时间在开始时间的后一天
if (curTime > startTime || curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
}
}
}
/**
* 主题设置时间
*/
data class ThemeTime(
// 开始小时
val beginHour: Int,
// 开始分钟
val beginMinute: Int,
// 结束小时
val endHour: Int,
// 结束分钟
val endMinute: Int,
// 开始时间
var startTime: String = "00:00",
// 结束时间
var stopTime: String = "00:00"
) : Serializable {
init {
startTime = "${upTo2String(beginHour)}:${upTo2String(beginMinute)}"
stopTime = "${upTo2String(endHour)}:${upTo2String(endMinute)}"
}
fun toTimerString(): String = "$startTime~$stopTime"
// 保存成长度为2的字符串
private fun upTo2String(value: Int): String {
val valueStr = "$value"
val sb = StringBuilder()
if (valueStr.length < 2) {
for (i in 0 until 2 - valueStr.length) {
sb.append("0")
}
}
sb.append(valueStr)
return sb.toString().substring(sb.length - 2)
}
}
设置代码
getBinding().rlMyThemeSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
int currentMode = NightModeUtils.Companion.getSpfThemeMode(AppContext.getInstance());
ThemeMode[] values = ThemeMode.values();
ThemeColorSelectAdapter.Bean[] items = new ThemeColorSelectAdapter.Bean[values.length];
for (int i = 0; i < values.length; i++) {
String title = AppContext.getInstance().getString(values[i].getStringValueId());
ThemeColorSelectAdapter.Bean bean = new ThemeColorSelectAdapter.Bean();
bean.title = title;
bean.color = values[i].getColor();
items[i] = bean;
}
ThemeColorSelectAdapter arrayAdapter = new ThemeColorSelectAdapter(
getActivity(), R.layout.view_color_check_item, items);
builder.setSingleChoiceItems(arrayAdapter, currentMode, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != currentMode) {
dialog.dismiss();
ThemeMode value = values[which];
NightModeUtils.getInstance(AppContext.getInstance()).setThemeMode(value);
if (currentMode == 0 || which == 0) {
//call setTheme
NightModeUtils.getInstance(getContext()).applySetting(getContext());
//如果重启会发现部分没生效,深色模式的切换是不需要重启就能生效的,如果不先调用切换模式代码,调用recreate也是没用的。
} else {//setTheme没用
getActivity().recreate();
}
updateThemeStatusTextView();
}
}
});
builder.setTitle(AppContext.getStr(R.string.deep_color_theme_setting));
builder.show();
}
});
thememode
enum class ThemeMode(val intValue: Int, val stringValueId: Int,val color:Int) {
MODE_ALWAYS_ON(0, R.string.theme_mode_darkmode,R.color.black_no_dark),
MODE_ALWAYS_OFF(1, R.string.theme_mode_default_blue,R.color.themeColorNoDark),
MODE_FOLLOW_SYSTEM(2, R.string.theme_mode_dark_follow_system,R.color.themeColorNoDark),
BLUE_THEME(3, R.string.theme_blue,R.color.themeColorBlueNoDark),
PURPLE_THEME(4, R.string.theme_purple,R.color.themeColorPurpleNoDark),
GREEN_THEME(5, R.string.theme_green,R.color.themeColorGreenNoDark),
YELLOW_THEME(6, R.string.yellow,R.color.themeColorYellowNoDark),
BROWN_THEME(7, R.string.theme_brown,R.color.themeColorBrownNoDark),
GREY_THEME(8, R.string.theme_grey,R.color.themeColorGreyNoDark),
AMBER_THEME(9, R.string.theme_amber,R.color.themeColorAmberNoDark),
CYAN_THEME(10, R.string.theme_cyan,R.color.themeColorCyanNoDark),
DEEP_ORANGE_THEME(11, R.string.theme_deep_orange,R.color.themeColorDeepOrangeNoDark),
BLACK_THEME(12, R.string.theme_black,R.color.black_no_dark);
// MODE_TIMER(30, R.string.theme_mode_3);
companion object {
@JvmStatic
fun parseOfInt(intValue: Int) : ThemeMode {
return when(intValue) {
MODE_ALWAYS_ON.intValue -> MODE_ALWAYS_ON
MODE_ALWAYS_OFF.intValue -> MODE_ALWAYS_OFF
MODE_FOLLOW_SYSTEM.intValue -> MODE_FOLLOW_SYSTEM
// MODE_TIMER.intValue -> MODE_TIMER
BLUE_THEME.intValue -> BLUE_THEME
YELLOW_THEME.intValue -> YELLOW_THEME
PURPLE_THEME.intValue -> PURPLE_THEME
GREEN_THEME.intValue -> GREEN_THEME
BROWN_THEME.intValue -> BROWN_THEME
GREY_THEME.intValue -> GREY_THEME
CYAN_THEME.intValue -> CYAN_THEME
AMBER_THEME.intValue -> AMBER_THEME
DEEP_ORANGE_THEME.intValue -> DEEP_ORANGE_THEME
BLACK_THEME.intValue -> BLACK_THEME
// BLACK_THEME.intValue,!in 0.. 30-> BLACK_THEME
else -> MODE_FOLLOW_SYSTEM
}
}
}
}
配色参考
http://mcg.mbitson.com/#!?mcgpalette0=%235768fe
https://www.materialpalette.com/light-blue/blue-grey
https://codecrafted.net/randommaterial
网友评论