2019独角兽企业重金招聘Python工程师标准>>>
关于夜间模式的总结
1.目前自己做的案例
- 1. 那么有两种方式可以实现夜间模式
- 1:修改theme,重启Activity
- 优点:正儿八经的夜间模式,配色看着舒服
- 缺点:图片刺眼、闪屏
- 2:使用一个带黑色带透明度的View,盖在现有的activity上【遮罩层】
- 优点:不用重启activity,不闪屏;加上透明度过渡动画,模式之间切换非常舒服,解决了1中,白底图片依旧刺眼的问题。;
- 缺点:配色没变化,就算带上墨镜,白天依旧是白天。
- 1:修改theme,重启Activity
- 2.使用步骤
- 1.首先,在values下要准备好三个文件,没有就自己创建
-
-
- 说明: attrs.xml(声明属性的类型,布局xml中用) reference可以使用系统的资源ID,比如R.color.gray; color可以直接使用#ffffff颜色代码
-
-
-
- colors.xml(调色板,集中管理颜色hex)遵循 优秀格式规范 ,即调色板模式,避免使用btn1,btn2,fontTitle,fontText之类的颜色名。
-
#fafafa
#f3f3f3
#cccccc
#777
#383838
#8e9ea4
#34515c
#1e3e4a
#90000000
-
-
- styles.xml(日间、夜间主题)
-
-
- 2.定义Activity父类和Application,自动托管日间、夜间模式
- 说明:BaseApplication就是自己包装的Application,通过它,保存日间、夜间模式
- Application和Activity一样是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息。
- android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享等,数据缓存等操作。
- 在自定义Application中
- 2.定义Activity父类和Application,自动托管日间、夜间模式
@Override
public void onCreate() {
super.onCreate();
……
//记录夜间模式状态。这个SP值很重要,不要随便清理SP中的值
mSp = PreferenceManager.getDefaultSharedPreferences(this);
mIsNightMode = mSp.getBoolean(PARAM_IS_NIGHT_MODE, false);
}
private boolean mIsNightMode;
private SharedPreferences mSp;
private static final String PARAM_IS_NIGHT_MODE = "PARAM_IS_NIGHT_MODE";
public boolean isNightMode() {
return mIsNightMode;
}
public void setIsNightMode(boolean isNightMode) {
if (mIsNightMode == isNightMode)
return;
mIsNightMode = isNightMode;
mSp.edit().putBoolean(PARAM_IS_NIGHT_MODE, mIsNightMode).apply();
}
-
-
- 在BaseActivity中
-
@Override
protected void onCreate(Bundle savedInstanceState) {
mBaseApp = (BaseApplication) getApplication();
if (mBaseApp.isNightMode()){
setTheme(isSwipeToClose() ? R.style.AppTheme_night_transparent : R.style.AppTheme_night);
} else{
setTheme(isSwipeToClose() ? R.style.AppTheme_day_transparent : R.style.AppTheme_day);
}
super.onCreate(savedInstanceState);
//夜间模式
mIsAddedView = false;
if (mBaseApp.isNightMode()) {
initNightView();
mNightView.setBackgroundResource(R.color.night_mask);
}
}
@Override
protected void onDestroy() {
if (mIsAddedView) {
mBaseApp = null;
mWindowManager.removeViewImmediate(mNightView);
mWindowManager = null;
mNightView = null;
}
super.onDestroy();
}
protected void initNightView() {
if (mIsAddedView)
return;
WindowManager.LayoutParams mNightViewParam = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mNightView = new View(this);
mWindowManager.addView(mNightView, mNightViewParam);
mIsAddedView = true;
}
protected void ChangeToDay() {
mBaseApp.setIsNightMode(false);
mNightView.setBackgroundResource(android.R.color.transparent);
}
protected void ChangeToNight() {
mBaseApp.setIsNightMode(true);
initNightView();
}
调用方式
isNight = BaseApplication.getInstance().isNightMode();
if (isNight) {
ChangeToDay();
} else {
ChangeToNight();
}
recreate();
-
- 3.如何在布局中引用资源
- 3.关于WebView网页如何实现日间、夜间模式
- 先了解js的切换夜间模式的点击事件接口
-
- 在代码里写【关键代码】
ws = webView.getSettings();
ws.setJavaScriptEnabled(true);
webView.setWebViewClient(new MyWebViewClient());
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
view.getSettings().setJavaScriptEnabled(true);
super.onPageFinished(view, url);
if (isNight) {
webView.loadUrl("javascript:toggleClassTest()");
}
}
}
2.简单优雅使用Android7.0实现夜间模式
- 1.关于Android7.0夜间模式新特性
- 事实上,日间模式与夜间模式就是给APP定义并应用两套不同颜色的主题。用户可以自动或者手动的开启。
- Android 6.0 Marshmallow 预览版中曾经短暂出现过相关的夜间模式的功能,只是在正式版中被移除了,在Android 7.0 Nougat上,用户们再次经历了「得而复失」的遗憾,在开发者预览版中,夜间模式和暗色模式先是开启,然后有再次被移除。而在正式版中,夜间模式也没有出现。但其实相关的代码一直存在于系统中,只是默认没有被开启。
- 2.实现步骤
- 1.添加依赖库
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
由于Support Library在23.2.0的版本中才添加了Theme.AppCompat.DayNight主题,所以依赖的版本必须是高于23.2.0的,并且,这个特性支持的最低SDK版本为14,所以,需要兼容Android 4.0的设备,是不能使用这个特性的,在API Level 14以下的设备会默认使用亮色主题。不过现在4.0以下的设备应该比较少了吧,毕竟微信的minSdkVersion都设置为14了。
-
- 2.准备资源
-
-
- 1.让我们自己的主题继承并应用DayNight主题。
-
-
-
- 2.新建资源文件
-
新建夜间模式资源文件夹:在res目录下新建values-night文件夹,然后在此目录下新建colors.xml文件在夜间模式下的应用的资源。当然也可以根据需要新建drawable-night,layout-night等后缀为-night的夜间资源文件夹。
在value中的color文件
#009688
#00796B
#009688
#616161
@android:color/white
在value-night的color文件
#35464e
#212a2f
#212a2f
#616161
#212a2f
-
-
- 3. 使Activity继承自AppCompatActivity
- 3.在自定义Application中
-
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
// the 'theme' has two values, 0 and 1
// 0 --> day theme, 1 --> night theme
if (getSharedPreferences("user_settings",MODE_PRIVATE).getInt("theme", 0) == 0) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
}
}
注意:
这里AppCompatDelegate.setDefaultNightMode()方法可以接受的参数值有4个:
-
-
-
- MODE_NIGHT_NO. (一直应用日间(light)主题).
- MODE_NIGHT_YES. (一直使用夜间(dark)主题).
- MODE_NIGHT_AUTO. (根据当前时间在day/night主题间切换).
- MODE_NIGHT_FOLLOW_SYSTEM(默认选项)(跟随系统,通常为MODE_NIGHT_NO).
-
-
-
- 4.动态调用切换夜间模式
SharedPreferences sp = getSharedPreferences("user_settings",MODE_PRIVATE);
if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES) {
sp.edit().putInt("theme", 0).apply();
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
} else {
sp.edit().putInt("theme", 1).apply();
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
}
//过渡动画效果,防止切换夜间模式闪屏
getWindow().setWindowAnimations(R.style.WindowAnimationFadeInOut);
recreate();
注意:
在调用recreate()方法之前,还可以创建一些动画进行过渡。
过渡动画
fade_in.xml动画文件
-
- 5.设置自定义属性,比如文字,按钮,容器背景等颜色
android:textColor="@color/textColor"
这样就可以根据属性切换字体颜色
values中color
#FF0000
night-values中color
#039BE5
-
- 6.注意事项
在Android 6.0及以下的设备上,本项目运行时会有切换的过渡动画效果,但是不支持Android 7.0及以上的设备