当下很多app都实现了夜间模式,其实个人感觉用着并不舒服,黑不溜秋的。不过总会有很多人想要这个需求,这不,最近也遇到了。于是上网搜了搜资料。这里简单记录下实现方法。
效果图
网上很多文章都讲解了好几种方案,不过总会有这样那样的问题,如车载模式之类的,有些有闪烁现象。所以这里我就用了下最麻烦的那种方案,通过定义attrs来实现的。
实现方式
在网上看到了一个大神写好的类,我也是直接拿过来用了
声明:这两个类为网上拿过来的,这里就不贴了,需要的请下载Demo
这里面首先写好界面,然后根据界面的控件来定义attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="btn_bg" format="color|reference"/>
<attr name="ui_background" format="color|reference"/>
</resources>
网上很多讲解都说要再布局文件中写background=”?attr/ui_background”,这样写确实很麻烦,很多布局都这样写应该很坑了吧。其实不用写,直接在代码里设置就行了。唯一麻烦的就是每个Activity里面都有进行夜间模式的切换。
Theme
值得注意的是,这个代码要在values,values-v21里的styles都写一遍,不然只能适配21以下或21以上之中的一种。
<!--白天主题-->
<style name="DayTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="btn_bg">@drawable/shape_bg_button</item>
<item name="ui_background">@color/white</item>
</style>
<!--夜间主题-->
<style name="NightTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimaryNight</item>
<item name="colorPrimaryDark">@color/colorPrimaryDarkNight</item>
<item name="colorAccent">@color/colorAccentNight</item>
<item name="btn_bg">@drawable/shape_bg_button_night</item>
<item name="ui_background">@color/grey</item>
</style>
代码实现
重要的地方都已经标注出来了
{
super.onCreate(savedInstanceState);
/**
* 注意此处代码写到setContentView前面
*/
mDayNightHelper = new DayNightHelper(this);
if (mDayNightHelper.isDay()) {
setTheme(R.style.DayTheme);
} else {
setTheme(R.style.NightTheme);
}
setContentView(R.layout.activity_main);
mText = (TextView) findViewById(R.id.tv);
mContainer = (LinearLayout) findViewById(R.id.activity_main);
mToolBar = (Toolbar) findViewById(R.id.tool_bar);
mToolBar.setTitle("");
setSupportActionBar(mToolBar);
mSwitch = (Button) findViewById(R.id.btn_switch);
mSwitch.setOnClickListener(this);
if (mDayNightHelper.isDay()) {
mText.setText("Day");
} else {
mText.setText("Night");
}
/**
* 初始化的时候也要切换模式
*/
switchMode();
}
核心代码
切换的时候直接调用这两个方法就行了
不要忘记修改状态栏
/**
* 修改主题
*/
private void changeTheme() {
if (mDayNightHelper.isDay()) {
mDayNightHelper.setMode(DayNight.NIGHT);
setTheme(R.style.NightTheme);
mText.setText("Night");
} else {
mDayNightHelper.setMode(DayNight.DAY);
setTheme(R.style.DayTheme);
mText.setText("Day");
}
}
/**
* 修改界面颜色
*/
private void switchMode() {
TypedValue bgContainer = new TypedValue();
TypedValue bgSwitch = new TypedValue();
TypedValue bgToolBar = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.btn_bg, bgSwitch, true);
theme.resolveAttribute(R.attr.ui_background, bgContainer, true);
theme.resolveAttribute(R.attr.colorPrimary, bgToolBar, true);
mSwitch.setBackgroundResource(bgSwitch.resourceId);
mContainer.setBackgroundResource(bgContainer.resourceId);
mToolBar.setBackgroundResource(bgToolBar.resourceId);
/**
* 不可忘记
*/
switchStatusBar();
}
/**
* switch statusBar
*/
private void switchStatusBar() {
if (Build.VERSION.SDK_INT >= 21) {
TypedValue primaryDark = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.colorPrimaryDark, primaryDark, true);
getWindow().setStatusBarColor(getResources().getColor(primaryDark.resourceId));
}
}
2292

被折叠的 条评论
为什么被折叠?



