手机软件换成夜间模式操作是qq自动弹出登陆界面的界面和字体都是白的看不清怎么办

android实战项目学习(1)
在网上看到很多童鞋都说用什么什么框架来实现这个功能,然后仔细去看一下各个推荐的框架,发现其实都是动态换肤的,动态换肤可比夜间模式要复杂多了,未免大材小用了。说实话,我一直没用什么好思路,虽然网上有童鞋提供了一种思路是通过 setTheme 然后再 recreate Activity 的方式,但是这样带来的问题是非常多的,看起来就相当不科学(为什么不科学,后文会说)。于是,直接想到了去逆向分析那些夜间模式做得好的应用的源代码,学习他们的实现套路。所以,本文的实现思路来自于编写这些应用的夜间模式功能的童鞋,先在这里向他们表示感谢。我的手机里面使用高频的应用不少,其中简书和知乎是属于夜间模式做得相当
nice 的。先给两个效果图大家对比感受下
如果大家仔细观察,肯定会发现,知乎的切换效果更漂亮些,因为它有一个渐变的效果。那么它们的夜间模式到底是如何实现的呢?别急接着往下看,你也可以。
这里先展示一下我的实现效果吧
简书实现效果
知乎实现效果
此处分为两个部分,一部分是 xml 文件中要干的活,一部分是 Java 代码要实现的活,先说 xml 吧。
首先,先写一套UI界面出来,上方左边是两个 TextView,右边是两个 CheckBox,下方是一个 RecyclerView ,实现很简单,这里我不贴代码了。
接着,在 styles 文件中添加两个 Theme,一个是日间主题,一个是夜间主题。它们的属性都是一样的,唯一区别在于颜色效果不同。
name=&DayTheme& parent=&Theme.AppCompat.Light.DarkActionBar&&
& =&&&@color/colorPrimary&/item&
&item name=&colorPrimaryDark&&@color/colorPrimaryDark&/item&
&item name=&colorAccent&&@color/colorAccent&/item&
&item name=&clockBackground&&@android:color/white&/item&
&item name=&clockTextColor&&@android:color/black&/item&
name=&NightTheme& parent=&Theme.AppCompat.Light.DarkActionBar&&
&item name=&colorPrimary&&@color/color3F3F3F&/item&
&item name=&colorPrimaryDark&&@color/color3A3A3A&/item&
&item name=&colorAccent&&@color/color868686&/item&
&item name=&clockBackground&&@color/color3F3F3F&/item&
&item name=&clockTextColor&&@color/color8A9599&/item&
需要注意的是,上面的 clockTextColor 和 clockBackground 是我自定义的 color 类型属性
&?xml version=&1.0& encoding=&utf-8&?&
name=&clockBackground& format=&color& /&
name=&clockTextColor& format=&color& /&
然后再到所有需要实现夜间模式功能的 xml 布局文件中,加入类似下面设置,比如我在 RecyclerView 的 Item 布局文件中做了如下设置
稍稍解释下其作用,如 TextView 里的 android:textColor=&?attr/clockTextColor& 是让其字体颜色跟随所设置的 Theme。到这里,xml 需要做的配置全部完成,接下来是 Java 代码实现了。
Java 代码实现
大家可以先看下面的实现代码,看不懂的童鞋可以边结合我代码下方实现思路解说。
package com.clock.study.
import ...
* 夜间模式实现方案
* @author Clock
public class DayNightActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {
private final static String TAG = DayNightActivity.class.getSimpleName();
/**用于将主题设置保存到SharePreferences的工具类**/
private DayNightHelper mDayNightH
private RecyclerView mRecyclerV
private LinearLayout mHeaderL
private List&RelativeLayout& mLayoutL
private List&TextView& mTextViewL
private List&CheckBox& mCheckBoxL
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
initData();
initTheme();
setContentView(R.layout.activity_day_night);
initView();
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(new SimpleAuthorAdapter());
mHeaderLayout = (LinearLayout) findViewById(R.id.header_layout);
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);
mCheckBoxList.add(ckbJianshu);
CheckBox ckbZhihu = (CheckBox) findViewById(R.id.ckb_zhihu);
ckbZhihu.setOnCheckedChangeListener(this);
mCheckBoxList.add(ckbZhihu);
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();
private void initData() {
mDayNightHelper = new DayNightHelper(this);
private void initTheme() {
if (mDayNightHelper.isDay()) {
setTheme(R.style.DayTheme);
setTheme(R.style.NightTheme);
* 切换主题设置
private void toggleThemeSetting() {
if (mDayNightHelper.isDay()) {
mDayNightHelper.setMode(DayNight.NIGHT);
setTheme(R.style.NightTheme);
mDayNightHelper.setMode(DayNight.DAY);
setTheme(R.style.DayTheme);
* 使用简书的实现套路来切换夜间主题
private void changeThemeByJianShu() {
toggleThemeSetting();
refreshUI();
* 使用知乎的实现套路来切换夜间主题
private void changeThemeByZhiHu() {
showAnimation();
toggleThemeSetting();
refreshUI();
* 刷新UI界面
private void refreshUI() {
TypedValue background = new TypedValue();//背景色
TypedValue textColor = new TypedValue();//字体颜色
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.clockBackground, background, true);
theme.resolveAttribute(R.attr.clockTextColor, 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));
int childCount = mRecyclerView.getChildCount();
for (int childIndex = 0; childIndex & childC childIndex++) {
ViewGroup childView = (ViewGroup) mRecyclerView.getChildAt(childIndex);
childView.setBackgroundResource(background.resourceId);
View infoLayout = childView.findViewById(_layout);
infoLayout.setBackgroundResource(background.resourceId);
TextView nickName = (TextView) childView.findViewById(R.id.tv_nickname);
nickName.setBackgroundResource(background.resourceId);
nickName.setTextColor(resources.getColor(textColor.resourceId));
TextView motto = (TextView) childView.findViewById(R.id.tv_motto);
motto.setBackgroundResource(background.resourceId);
motto.setTextColor(resources.getColor(textColor.resourceId));
//让 RecyclerView 缓存在 Pool 中的 Item 失效
//那么,如果是ListView,要怎么做呢?这里的思路是通过反射拿到 AbsListView 类中的 RecycleBin 对象,然后同样再用反射去调用 clear 方法
Class&RecyclerView& recyclerViewClass = RecyclerView.
Field declaredField = recyclerViewClass.getDeclaredField(&mRecycler&);
declaredField.setAccessible(true);
Method declaredMethod = Class.forName(RecyclerView.Recycler.class.getName()).getDeclaredMethod(&clear&, (Class&?&[]) new Class[0]);
declaredMethod.setAccessible(true);
declaredMethod.invoke(declaredField.get(mRecyclerView), new Object[0]);
RecyclerView.RecycledViewPool recycledViewPool = mRecyclerView.getRecycledViewPool();
recycledViewPool.clear();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
refreshStatusBar();
* 刷新 StatusBar
private void refreshStatusBar() {
if (Build.VERSION.SDK_INT &= 21) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
getWindow().setStatusBarColor(getResources().getColor(typedValue.resourceId));
* 展示一个切换动画
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() {
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
((ViewGroup) decorView).removeView(view);
objectAnimator.start();
* 获取一个 View 的缓存视图
* @param view
private Bitmap getCacheBitmapFromView(View view) {
final boolean drawingCacheEnabled =
view.setDrawingCacheEnabled(drawingCacheEnabled);
view.buildDrawingCache(drawingCacheEnabled);
final Bitmap drawingCache = view.getDrawingCache();
if (drawingCache != null) {
bitmap = Bitmap.createBitmap(drawingCache);
view.setDrawingCacheEnabled(false);
实现思路和代码解说:
DayNightHelper 类是用于保存夜间模式设置到 SharePreferences 的工具类,在 initData 函数中被初始化,其他的 View 和 Layout 都是界面布局,在 initView 函数中被初始化;在 Activity 的 onCreate 函数调用 setContentView 之前,需要先去 setTheme,因为当 View 创建成功后 ,再去 setTheme 是无法对 View 的 UI 效果产生影响的;onCheckedChanged 用于监听日间模式和夜间模式的切换操作;refreshUI 是本实现的关键函数,起着切换效果的作用,通过 TypedValue 和 Theme.resolveAttribute 在代码中获取 Theme 中设置的颜色,来重新设置控件的背景色或者字体颜色等等。需要特别注意的是 RecyclerView 和 ListView 这种比较特殊的控件处理方式,代码注释中已经说明,大家可以看代码中注释;refreshStatusBar 用于刷新顶部通知栏位置的颜色;showAnimation 和 getCacheBitmapFromView 同样是本实现的关键函数,getCacheBitmapFromView 用于将 View 中的内容转换成 Bitmap(类似于截屏操作那样),showAnimation 是用于展示一个渐隐效果的属性动画,这个属性作用在哪个对象上呢?是一个 View ,一个在代码中动态填充到 DecorView 中的 View(不知道 DecorView 的童鞋得回去看看 Android Window 相关的知识)。知乎之所以在夜间模式切换过程中会有渐隐效果,是因为在切换前进行了截屏,同时将截屏拿到的
Bitmap 设置到动态填充到 DecorView 中的 View 上,并对这个 View 执行一个渐隐的属性动画,所以使得我们能够看到一个漂亮的渐隐过渡的动画效果。而且在动画结束的时候再把这个动态添加的 View 给 remove 了,避免了 Bitmap 造成内存飙升问题。对待知乎客户端开发者这种处理方式,我必须双手点赞外加一个大写的服。
到这里,实现套路基本说完了,简书和知乎的实现套路如上所述,区别就是知乎多了个截屏和渐隐过渡动画效果而已。
整理逆向分析的过程,也对夜间模式的实现有了不少思考,希望与各位童鞋们探讨分享。
最初步的逆向分析过程就发现了,知乎和简书并没有引入任何第三方框架来实现夜间模式,为什么呢?
因为我看到的大部分都实现夜间模式的思路都是用开源的换肤框架,或多或少存在着些 BUG。简书和知乎不用可能是出于框架不稳定性,以及我前面提到的用换肤框架来实现夜间模式大材小用吧。(我也只是瞎猜,哈哈哈)
前面我提到,通过 setTheme 然后再去 Activity recreate 的方案不可行,为什么呢?
我认为不可行的原因有两点,一个是 Activity recreate 会有闪烁效果体验不加,二是 Activity recreate 涉及到状态状态保存问题,如自身的状态保存,如果 Activity 中包含着多个 Fragment ,那就更加头疼了。
知乎和简书设置夜间模式的位置,有点巧妙,巧妙在哪?
知乎和简书出发夜间模式切换的地方,都是在 MainActivity 的一个 Fragment 中。也就是说,如果你要切换模式时,必须回到主界面,此时只存在主界面一个 Activity,只需要遍历主界面更新控件色调即可。而对于其他设置夜间模式后新建的 Activity ,只需要在 setContentView 之前做一下判断并 setTheme 即可。
关于简书和知乎夜间模式功能实现的套路就讲解到这里,整个实现套路都是我通过逆向分析简书和知乎的代码取得,这里再一次向实现这些代码的童鞋以示感谢。当然,上面的代码我是经过精简提炼过的,在原先简书和知乎客户端中的实现代码还做了相应的抽象设计和递归遍历等等,这里是为了方便讲解而做了精简。如果有童鞋喜欢这种实现套路,也可以自己加以抽象封装。这里也推荐各位童鞋一个我常用的思路,就是当你对一个功能没有思路时,大可找一些实现了这类功能的优秀应用进行逆向代码分析。需要实现代码的童鞋,可以访问:
文/D_clock爱吃葱花(简书作者)
原文链接:/p/3b55e84742e5
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6772次
排名:千里之外
原创:36篇
转载:50篇
(3)(5)(4)(30)(46)云看点app怎么开启夜间模式?云看点app开启夜间模式的方法
时间:日来源:手机世界
云看点开启夜间模式方法。相信很多小伙伴都是在晚上观看云看点文章,为了避免长时间的观看眼睛受到刺激,可以开启夜间模式哦,那么要怎么开启夜间模式呢?现在小编就教大家云看点开启夜间模式方法。
相关教程:云看点修改登录密码教程
打开云看点,点击右下角的【我的】,然后点击【夜间模式】旁边的【按钮】即可。(如下图)
云看点 致力于微资讯热点传递,让你及时了解最新热点,参与及浏览精彩绝伦的网友评论。海量信息,精选专题,聚焦热点,全新视角…
页面地址:/android/110883.html内容字号:
段落设置:
字体设置:
iOS中“DKNightVersion”的简单使用(夜间模式)
Banner.png
相信大家都遇到过白天/夜间模式的切换,在万能的github上就有这么一个牛X的库-----&DKNightVersion传送门&,写这篇文章只是简单的记录下来自己使用DKNightVersion的过程,目前本人使用到的都是基本的功能,欢迎留言补充。
先来看看我写的小Demo效果图吧( &_&!!!,凑合看吧)&
DKNightVersion实现原理(个人猜测)
我觉得DKNightVersion实现的基本原理应该是利用一个单例存储颜色, 通过runtime中的&objc_setAssociatedObject 和 objc_getAssociatedObject&来完成对象间传递所要保存的颜色。具体怎么实现的我也不太清楚还没到那层次,还望懂的大神不吝赐教。
下面是简单使用代码
#import &ViewController.h&
#import &DKNightVersion/DKNightVersion.h&
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISwitch *
@property (weak, nonatomic) IBOutlet UIButton *
@property (weak, nonatomic) IBOutlet UIBarButtonItem *leftB
@property (weak, nonatomic) IBOutlet UIBarButtonItem *rightB
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self changeColor];
- (void)changeColor
UILabel *navLabel = [[UILabel alloc] init];
navLabel.text = @&夜间模式&;
[navLabel sizeToFit];
self.navigationItem.titleView = navL
self.view.dk_backgroundColorPicker = DKColorPickerWithKey(BG);
navigationLabel.dk_textColorPicker = DKColorPickerWithKey(TEXT);
[self.button dk_setTitleColorPicker:DKColorPickerWithKey(TINT) forState:UIControlStateNormal];
self.switchs.dk_tintColorPicker = DKColorPickerWithKey(TINT);
self.leftButton.dk_tintColorPicker = DKColorPickerWithKey(TINT);
self.rightButton.dk_tintColorPicker = DKColorPickerWithKey(TINT);
- (IBAction)open:(id)sender
if ([self.dk_manager.themeVersion isEqualToString:DKThemeVersionNight]) {
[self.dk_manager dawnComing];
[self.dk_manager nightFalling];
- (IBAction)change:(id)sender
if (self.switchs.isOn) {
self.dk_manager.themeVersion = DKThemeVersionN
self.dk_manager.themeVersion = DKThemeVersionN
- (IBAction)left:(id)sender
self.dk_manager.themeVersion = @&RED&;
- (IBAction)right:(id)sender
self.dk_manager.themeVersion = DKThemeVersionN
&疑惑&我查看github上下载下来的Demo,发现他在切换到夜间模式的时候,电量、运营商、时间也会跟着变换,但是目前我这切换的时候没有,有待解决。
&吐槽&在使用的时候其实还挺简单的,但需要给每个控件进行颜色设置(图片至少需要准备两套 0.0),如果项目比较庞大,逐一设置还是比较累人的。
分享给小伙伴们:
本类最热新闻
48小时最热
0102030405060708910
CopyRight © 2015- , All Rights Reserved.
清屏网 版权所有 豫ICP备号微信字太小看不清怎么办?设置微信字体大小的教程
微信字太小看不清怎么办?想必有些近视用户都觉得微信的字体太小了吧,导致在玩微信的时候看字体越看越迷糊,不过现在微信更新功能可以设置字体大小了,用户们可以根据想要的字体大小而调整了,由于新功能肯定很多用户都不知道如何设置吧,今天小编就教大家微信如何设置字体大小。
软件名称:微信 手机通信软件 V6.0.1 for iPhone 苹果版软件大小:46.4MB更新时间:
软件名称:微信 6.0 for Android 官方中文免费安装版软件大小:27.8MB更新时间:
软件名称:微信HD for ipad V5.4.2官方版 平板电脑版软件大小:35.1MB更新时间:
软件名称:微信电脑版 for Mac V1.0.0.7 苹果电脑版软件大小:8.61MB更新时间:
1)首先打开微信,点击【我】,然后点击【设置】,进入界面点击【通用】。(如下图)
2)点击【字体大小】,在下方点圆点也左右拖动字体大小,在界面的字体也会跟着变化哦。(如下图)
3)小编是调到最大字体为例给大家看看字体的变化,最后点击【返回】即可设置完毕。(如下图)
相关推荐:
微信视频聊天窗口可以缩小吗?微信缩小窗口视频聊天的方法
晚上拍摄视频怎么才能清楚?微信小视频夜景加亮模式的使用方法
顶一下(0) 踩一下(0)
热门标签:}

我要回帖

更多关于 无法弹出wifi登陆界面 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信