android os夜间,DayNightModeChange_Android日间模式和夜间模式切换

先上酷炫的运行效果

ac23d3e481fc

day_night_themechange.gif

日夜间模式在app上面的使用场景还是很多的,特别是有关阅读类的app,不同的光线条件下让用户选择不同的主题模式那是必须得。其实实现这样的需求也很简单,下面就来看看我的方法吧。

实现前的分析

不同的模式下 View或activity需要设置不同的resource(这里resource可以是color、mipmap、style等资源),那么怎么让resource不同呢? 只需要让resource根据不同的模式设置不同的名称,然后根据不同的名称获取到不同的resourceId就可以了

具体示例

HomeActivity的代码如下:

package com.example.idea.daynightmodechange;

import android.app.Activity;

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.Toast;

import com.example.idea.daynightmodechange.config.Config;

import com.example.idea.daynightmodechange.theme.IThemeable;

import com.example.idea.daynightmodechange.theme.ThemeManager;

import com.example.idea.daynightmodechange.theme.ThemeUtils;

import butterknife.BindView;

import butterknife.ButterKnife;

public class HomeActivity extends Activity implements IThemeable {

@BindView(R.id.ll_container)

LinearLayout ll_container;

@BindView(R.id.tv_text1)

TextView tv_text1;

@BindView(R.id.tv_text2)

TextView tv_text2;

@BindView(R.id.iv_image)

ImageView iv_image;

@BindView(R.id.btn_change_mode)

Button btn_change_mode;

@BindView(R.id.btn_jump)

Button btn_jump;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

getThemeManager().applyTheme(HomeActivity.this, R.style.AppTheme);

setContentView(R.layout.act_home);

ButterKnife.bind(this);

initView();

}

private void initView() {

btn_change_mode.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

if (Config.currentTheme == ThemeManager.THEME.DAY) {

getThemeManager().changeTheme(ThemeManager.THEME.NIGHT);

} else {

getThemeManager().changeTheme(ThemeManager.THEME.DAY);

}

applyTheme();

}

});

btn_jump.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

startActivity(new Intent(HomeActivity.this,TestStyleActivity.class));

}

});

}

@Override

public void applyTheme() {

getThemeManager().applyBackgroundColor(ll_container, R.color.color_home_bg);

getThemeManager().applyTextColor(tv_text1, R.color.color_text);

getThemeManager().applyImageResource(iv_image, R.drawable.shape_iv_bg);

getThemeManager().applyBackgroundDrawable(btn_jump, R.drawable.selector_text_bg);

getThemeManager().applyBackgroundDrawable(btn_change_mode, R.drawable.selector_text_bg);

}

@Override

public ThemeManager getThemeManager() {

return ThemeManager.getInstance();

}

@Override

public boolean isThemeEnable() {

return true;

}

}

对应的布局文件:

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/ll_container"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@color/color_home_bg"

android:orientation="vertical"

tools:context="com.example.idea.daynightmodechange.HomeActivity">

android:id="@+id/tv_text1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="17dp"

android:text="这是测试的TextView 要改变"

android:textColor="@color/color_text"

android:textSize="17sp" />

android:id="@+id/tv_text2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="17dp"

android:text="这是测试的TextView 不改变模式"

android:textColor="@color/color_text"

android:textSize="17sp" />

android:id="@+id/iv_image"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_gravity="center_horizontal"

android:layout_marginTop="17dp"

android:src="@drawable/shape_iv_bg" />

android:id="@+id/btn_change_mode"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="17dp"

android:background="@drawable/selector_text_bg"

android:padding="10dp"

android:text="切换模式"

android:textSize="17sp" />

android:id="@+id/btn_jump"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="17dp"

android:background="@drawable/selector_text_bg"

android:padding="10dp"

android:text="跳转到下个Activity"

android:textSize="17sp" />

用一个枚举类型来表示你需要切换的模式,这里我只使用了日间模式和夜间模式这两个。

public static enum THEME {

DAY, NIGHT("_night"); //你������可以添加多种模式在这里,不同的模式应该具有不同的后缀

String resPrefix;

private THEME() {

resPrefix = "";

}

private THEME(String prefix) {

resPrefix = prefix;

}

/**

* 资源名称

* @param name

* @return

*/

public String formatResName(String name) {

return name + resPrefix;

}

public boolean hasResPrefix() {

return !TextUtils.isEmpty(resPrefix);

}

}

这里通过切换模式后ll_container的背景颜色的改变来分析

a.我在colors资源里,为ll_container准备了两份颜色值,这里一定要在

"color_home_bg"后面加上"_night",与枚举相对应,为了后面通过资源Id和枚举类型获取对应的资源Id。

#e5e5e5

#80444444

b.当我要切换模式的时候,针对ll_container这个view调用

getThemeManager().applyBackgroundColor(ll_container, R.color.color_home_bg);

c.我们来看一下它具体的方法实现

public ThemeManager applyBackgroundColor(Context context, View view,

int backgroundResourceId) {

view.setBackgroundResource(ThemeUtils.processColorResId(context,

this.theme, backgroundResourceId));

return this;

}

/**

*

* @param view 要设置的view

* @param backgroundResourceId 资源id

* @return

*/

public ThemeManager applyBackgroundColor(View view, int backgroundResourceId) {

return applyBackgroundColor(view.getContext(), view,

backgroundResourceId);

}

d.ThemeUtils.processColorResId(context,this.theme, backgroundResourceId)这个方法的作用是根据当前资源id和theme获取到对应的资源id

public static int processColorResId(Context context,

ThemeManager.THEME theme, int resourceId) {

return processThemeResId(context, theme, "color", resourceId);

}

/**

*

* @param context

* @param theme 当前主题

* @param defType 对应的资源类别

* @param resourceId

* @return

*/

private static int processThemeResId(Context context,

ThemeManager.THEME theme, String defType, int resourceId) {

if (theme.hasResPrefix() && isThemeEnable(context)) {

String strThemeResName = processThemeResName(theme, context

.getResources().getResourceName(resourceId));

return context.getResources().getIdentifier(strThemeResName,

defType, context.getPackageName());

} else {

return resourceId;

}

}

这样就完成了ll_contianer的背景色切换,是不是很easy.

切换别的view的资源与这个类似,这里就不一一列举了。

需要注意的地方

当我们app中使用沉浸式状态栏实现时候,一定希望状态栏和标题栏能在进行模式切换的时候改变样式,但是状态栏和标题栏的样式的切换只能在Activity的setContentView()方法之前执行,上面的方法就不能用来切换状态栏和标题栏的样式了。

想要切换状态栏和标题栏的样式,可以用recreate()方法来重启Activity来实现,Activity重启会有闪烁的问题可以通过动画来过渡。

后续

官方在Android Support Library 23.2开始支持了夜间模式切换,有关23.2的夜间模式切换,请戳这里【还没写】。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值