作者:Bgwan
链接:https://zhuanlan.zhihu.com/p/22520818
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

网上看到过大多实现夜间模式的效果,实现方式总结起来,发现好繁琐,大多数夜间模式实现都是基于另一套apk来,作为依赖实现,像QQ,微信,这种直接提供给你一套皮肤来切换背景,如果要做这个皮肤开发的工作量不小于一个软件的开发周期,而知乎简书这种夜间模式的实现就相对于更加轻量级了。

今天这里采用qydq/提供的an框架来简单快速实现夜间模式,an框架提供了两种方式实现夜间模式,一种比较简单,一种比较复杂。

Athor IP:sunshuntao(qydq)(莳萝花)。

Email:qyddai@gmail.com。

知乎地址:Android开发 - 知乎专栏

Begin

♥♥♥ 请关注后获取源码 ♥♥♥

创建时间:2016年08月29日;最近修改时间:2016年08月30日。

GitHub - qydq/an-maven-base: android studio创建github 的repository

Tips

1。前言(包含该项目主要实现的功能的简短说明,运行配置;可选)。

2。实现效果(如果没有可以省略,但是建议要包含,因为项目以后自己看到的时候会帮助自己理解)。

3。思路或使用(代码)。

## *** 使用方法 *** ##

4。重要知识点(总结,思考)。

5。内容参考(尊重原创)。

6。联系作者。

*** -----------------------------woshifengexian-----------------------------------***

2,实现效果

3。思路或使用(代码)。

稍微说一下,首先外面切换的时候,只是设置了部分区域的夜间模式,这里主要以示区别,你自己也可以试着把那个模块区域加上夜间模式,下面的内容会讲解到。

点击进去也设置了夜间模式,可以看到也是部分区域设置了夜间模式(这里是随便选了一种颜色就当作皮肤,你可以改成夜间模式灰色即可),因为点击后的界面我们要用第二种方式来实现夜间模式,这里以示区别。具体根据业务需求来采用相应的方法。

下面开始讲解两种夜间模式的实现方法。首先在编译build.gradle中加入an框架如下依赖,

自己备注一下:base应该是轻量级别的依赖关系,an应该是重量级的依赖,这里算是一个瑕疵。

compile 'com.github.qydq:an-maven-base:0.0.8'

1)第一种实现方法,稍微有点复杂。

首先我们需要一个夜间模式的帮助类,还有要找到需要设置夜间模式的Layout

//主题切换测试
private DayNightHelper mDayNightHelper;
private RecyclerView mRecyclerView;
private LinearLayout mHeaderLayout;
private List<RelativeLayout> mLayoutList;
private List<TextView> mTextViewList;
private List<CheckBox> mCheckBoxList;

在setContentView()之前,加入初始化的夜间模式主题,如

mDayNightHelper = new DayNightHelper(this);
initTheme();
setContentView(R.layout.activity_main);

initTheme()如下,作用是关闭应用第二次进入如果是夜间模式则显示夜间模式,反之亦然,

private void initTheme() {
if (mDayNightHelper.isDay()) {
setTheme(R.style.DayTheme);
} else {
setTheme(R.style.NightTheme);
}
}

简单的findViewById

mLayoutList = new ArrayList<>();
mLayoutList.add((RelativeLayout) findViewById(R.id.jianshu_layout));
mLayoutList.add((RelativeLayout) findViewById(R.id.zhihu_layout));
mTextViewList = new ArrayList<>();
mTextViewList.add((TextView) findViewById(R.id.tv_jianshu));
mTextViewList.add((TextView) findViewById(R.id.tv_zhihu));
mCheckBoxList = new ArrayList<>();
CheckBox ckbJianshu = (CheckBox) findViewById(R.id.ckb_jianshu);
ckbJianshu.setOnCheckedChangeListener(this);

其次是对某一事件的监听 ,修改主题,这里是CheckBox

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int viewId = buttonView.getId();
if (viewId == R.id.ckb_jianshu) {
changeThemeByJianShu(); } else if (viewId == R.id.ckb_zhihu) {
changeThemeByZhiHu();
}
}

这里讨论知乎的实现讨论,可以看到这里启动了一个夜间模式切换的动画,这样不至于一下子就变了背景。动画是实现的渐变效果,给用户好的体验效果。toggleThemeSetting是对CheckBox的事件监听来j。

/**
* 使用知乎的实现套路来切换夜间主题
*/
private void changeThemeByZhiHu() {
showAnimation();
toggleThemeSetting();
refreshUI();
}

showAnimation和toggleThemSetting的代码如下,

/**
* 展示一个切换动画
*/
private void showAnimation() {
final View decorView = getWindow().getDecorView();
Bitmap cacheBitmap = getCacheBitmapFromView(decorView);
if (decorView instanceof ViewGroup && cacheBitmap != null) {
final View view = new View(this);
view.setBackgroundDrawable(new BitmapDrawable(getResources(), cacheBitmap));
ViewGroup.LayoutParams layoutParam = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
((ViewGroup) decorView).addView(view, layoutParam);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);
objectAnimator.setDuration(300);
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
((ViewGroup) decorView).removeView(view);
}
});
objectAnimator.start();
}
}
/**
* 切换主题设置
*/
private void toggleThemeSetting() {
if (mDayNightHelper.isDay()) {
mDayNightHelper.setMode(DayNightMode.NIGHT);
setTheme(R.style.NightTheme);
} else {
mDayNightHelper.setMode(DayNightMode.DAY);
setTheme(R.style.DayTheme);
}
}

再者,开始更新UI,refresh当前的UI,initThem是进入是的模式是夜间还是白天。

TypedValue background = new TypedValue();//背景色
TypedValue textColor = new TypedValue();//字体颜色
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.anBackground, background, true);
theme.resolveAttribute(R.attr.anTextColor, textColor, true); mHeaderLayout.setBackgroundResource(background.resourceId);
for (RelativeLayout layout : mLayoutList) {
layout.setBackgroundResource(background.resourceId);
}
for (CheckBox checkBox : mCheckBoxList) {
checkBox.setBackgroundResource(background.resourceId);
}
for (TextView textView : mTextViewList) {
textView.setBackgroundResource(background.resourceId);
} Resources resources = getResources();
for (TextView textView : mTextViewList) {
textView.setTextColor(resources.getColor(textColor.resourceId));
}

最后,你不觉得很奇怪吗?就凭借上面的代码就可以实现夜间模式切换效果,未免太简单了吧,其实不用奇怪,就是这么简单,我们只要在加入an框架的background即可,这样,每次设置好相应的夜间模式或正常模式,an框架都会帮助去进行主题的设置。

在Layout布局代码中按照如下这样的标准加入相应的,属性。

<LinearLayout
android:id="@+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:background="?attr/anBackground"
android:orientation="vertical"> <RelativeLayout
android:id="@+id/jianshu_layout"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="?attr/anBackground"> <TextView
android:id="@+id/tv_jianshu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:background="?attr/anBackground"
android:text="简书夜间模式切换方案"
android:textColor="?attr/anTextColor" /> <CheckBox
android:id="@+id/ckb_jianshu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:background="?attr/anBackground" />
</RelativeLayout>

第一种方式的所有实现夜间模式套路,这里已经完全,完完全全给出来了,你不需要额外的配置,这样就可以完成夜间模式,但是相对于第二种方式就显得比较复杂了。an框架也提供的另一种简单的夜间模式,如2)中。

2)第二种夜间模式实现方式,简单夜间模式实现方式,如效果图第二个点击进入的窗口(即改变背景)

同样在CheckBox中,监听即可完成夜间模式的设置,下次启动则可以生效,从效果图可以看到,改变了主题颜色(改变主题也可以认为就是夜间模式,只不过换个颜色)上面也说了,不能写一个皮肤出来,大材小用。,业务也不需要。

@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
SharedPreferences.Editor editor = sp.edit();
if (sp.getBoolean("isNightMode", false)) {
editor.putBoolean("isNightMode", false);
editor.commit();
getWindow().getDecorView().setBackground(this.getResources().getDrawable(com.an.an_base.R.drawable.yy_drawable_bgnigt_shape));
} else {
editor.putBoolean("isNightMode", true);
editor.commit();
getWindow().getDecorView().setBackground(getResources().getDrawable(com.an.an_base.R.drawable.yy_drawable_bgday_shape));
}

从效果图也可以看到,之前设置的夜间模式,显示出来了,是因为我为了验证第一种(设置夜间模式的方法是否有效)而加入的代码,可以看到第一种夜间模式完全OK,加入了下面代码

mDayNightHelper = new DayNightHelper(this);
initTheme();
setContentView(R.layout.activity_create_code);
private void initTheme() {
if (mDayNightHelper.isDay()) {
setTheme(R.style.DayTheme);
} else {
setTheme(R.style.NightTheme);
}
}

4。重要知识点(总结,思考)。

引用了an框架,具体也可以参考,网易博客。

5。内容参考(尊重原创)。

第一种实现套路是参考知乎上另一位童鞋的夜间模式的实现套路修改而来的,这里已经完全简化了使用方式,通过本博客既可以快速集成。

参考,链接(我又上网找到了,但不是知乎的,是传送门也有参考)

知乎和简书的夜间模式实现套路_Android程序员

第二种为个人设计

6。联系作者。

## 联系作者。

Athor:sunshuntao(qydq)(莳萝花)。

Email:qyddai@gmail.com。

知乎地址:Android开发 - 知乎专栏

End

♥♥♥ 请关注后获取源码 ♥♥♥

至:授人以鱼,不如授人与渔,话不多说,yu前几篇博客已经介绍过,更多内容请关注。

Android 利用an框架快速实现夜间模式的两种套路的更多相关文章

  1. Android 高级UI设计笔记23:Android 夜间模式之 两种常用方法(降低屏幕亮度+替换theme)

    1. 夜间模式 所谓的夜间模式,就是能够根据不同的设定,呈现不同风格的界面给用户,而且晚上看着不伤眼睛.特别是一些新闻类App实现夜间模式是非常人性化的,增强用户体验. 2. 我根据网上的资料 以及自 ...

  2. Android 利用an框架快速实现网络请求(含下载上传文件)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/22573081来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. an框架的网络框架是完全 ...

  3. 内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式.

    内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式. 一丶IDT解析. 我们知道.IDT表中存放着各种中断信息.比如当我们调用int 3的时候,则会调用IDT表中的第三项来进行调用. 而函数 ...

  4. Android开发之使用sqlite3工具操作数据库的两种方式

    使用 sqlite3 工具操作数据库的两种方式 请尊重他人的劳动成果,转载请注明出处:Android开发之使用sqlite3工具操作数据库的两种方式 http://blog.csdn.net/feng ...

  5. 探究Repository模式的两种写法与疑惑

    现如今DDD越来越流行,园子里漫天都是介绍关于它的文章.说到DDD就不能不提Repository模式了,有的地方也叫它仓储模式. 很多时候我们对Repository都还停留在Copy然后使用的阶段, ...

  6. 单例Singleton模式的两种实现方法

    在设计模式中,有一种叫Singleton模式的,用它可以实现一次只运行一个实例.就是说在程序运行期间,某个类只能有一个实例在运行.这种模式用途比较广泛,会经常用到,下面是Singleton模式的两种实 ...

  7. Android夜间模式的几种实现

    一.直接修改widget颜色,这种方式实现起来最简单,但需要每个控件都去修改,太过复杂.例如: /** * 相应交互,修改控件颜色 * @param view */public void onMeth ...

  8. android利用apkplug框架实现主应用与插件通讯(传递随意对象)实现UI替换

    时光匆匆,乍一看已半年过去了,经过这半年的埋头苦干今天最终有满血复活了. 利用apkplug框架实现动态替换宿主Activity中的UI元素.以达到不用更新应用就能够更换UI样式的目的. 先看效果图: ...

  9. Android中实现全屏、无标题栏的两种办法

    在进行UI设计时,我们经常需要将屏幕设置成无标题栏或者全屏.要实现起来也非常简单,主要有两种方法:配置xml文件和编写代码设置. 1.在xml文件中进行配置 在项目的清单文件AndroidManife ...

随机推荐

  1. 网络最大流算法—Dinic算法及优化

    前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. ...

  2. Kinect 开发 —— 骨骼追踪进阶(上)

    Kinect传感器核心只是发射红外线,并探测红外光反射,从而可以计算出视场范围内每一个像素的深度值.从深度数据中最先提取出来的是物体主体和形状,以及每一个像素点的游戏者索引信息.然后用这些形状信息来匹 ...

  3. DG的数据保护模式

    DG的数据保护模式 数据保护膜有三种: – Maximum protection – Maximum availability – Maximum performance Maximum protec ...

  4. Vue移动端flexible.js+MuseUi

    因为公司有个项目需求,手机端的.之前就写了一个一样的项目,只不过是用原生的写的,心想刚写了个vue后台管理系统,何不也用vue写,所有就没有把之前的利用过来.那么问题来了,要让手机端自适应我们该怎么做 ...

  5. Android自定义视图

    Android框架为我们提供了大量的视图类来帮助我们做好展示信息以及同用户进行交互的工作.然后有时候,我们的app或许需要一些在Android内建视图之外特殊的视图,那么此时我们就需要自定义视图.下面 ...

  6. 26.event跨进程通信

    以id创建事件 ] = "myevent"; HANDLE event = CreateEventA(NULL, FALSE, FALSE, name); 设置事件 SetEven ...

  7. 2.1 Producer API官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.1 Producer API 2.1.生产者API 我们鼓励所有新开发的程序使用 ...

  8. eclipse创建maven

    第一步: 第二步 第三步: 第四步: 第五步: 第六步: <?xml version="1.0" encoding="UTF-8"?> <we ...

  9. Java调用jama实现矩阵运算

    Java调用jama实现矩阵运算 一.jama简介 Jama是一个基本的线性代数java包.包括一个基本的Matrix类和5个矩阵分解类. Matrix类提供了基本的线性代数数值运算的功能,不同的构造 ...

  10. 【Tomcat】严重: Context [/grouponAdminWeb] startup failed due to previous errors

    1 tomcat 6600启动报错[root@localhost webapps]#     sh /usr/local/apache-tomcat-6.0.37_6600/bin/startup.s ...