作者: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. IIS7下设置AD单点登录

    简介:IIS7下设置AD单点登录 1.选中网站,双击“身份验证”: 2.启用“Window身份验证”.禁用“匿名身份验证”.启用“基本身份验证”: 3.在“基本身份验证”上面点右键,选择“编辑”,输入 ...

  2. Swift视频教程,Swift千人学iOS开发编程语言

    此时大家站在同一起跑线.Swift语言将将是下一个风靡程序猿界的编程语言,是否能抢占先机,近在咫尺. 本期推荐Swift编程语言视频教程,内容包含:开发环境基本使用.数据类型和常量.数据自己主动检查和 ...

  3. ubuntu终端sudo java提示“command not found”解决办法

    我在ubuntu 12.04里想启动一个java程序,sudo java -jar xxx.jar,但是结果提示sudo:java:command not found. Ubuntu下用sudo运行j ...

  4. 简单的横向ListView实现(version 3.0)

    版本号2仅仅是简单的实现了当手指按下的时候listView的Item向左移动一定的距离,并没有随着手指的左右移动而左右滚动.在这个版本号3.0中将会实现随着手指的移动而滚动的目标:当手指向左移动的时候 ...

  5. POJ 题目1145/UVA题目112 Tree Summing(二叉树遍历)

    Tree Summing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8132   Accepted: 1949 Desc ...

  6. [分享]ip地址爬取过滤的shell

    http://www.hbbzy.me/分享ip地址爬取过滤的shell #!/bin/base #ip zhi地址匹配 #获取最新的ip地址 #author:haifeng #wget ftp:// ...

  7. visibility-控件的显示跟隐藏设置

    在Android开发中,大部分控件都有visibility这个属性,其属性有3个 visible:可见 invisible:不可见,但是会占据原来的位置 gone:不可见,也不会占据原来的位置 可见( ...

  8. HASH Partitioning--转载

    原文地址:https://dev.mysql.com/doc/refman/5.1/en/partitioning-hash.html HASH Partitioning [+/-] 18.2.3.1 ...

  9. css实现一个缺口小三角

    .square{ width:; height:; margin:0 auto; border:6px solid transparent; border-bottom: 6px solid red; ...

  10. gomail发送附件

    采用github.com/go-gomail/gomail/ 的邮件功能,可以发送附件 以及html文档,下面是其给出的demo,测试通过. package main //cmd: go get go ...