Android主题切换之探究白天和夜间模式

Android主题切换之探究白天和夜间模式,第1张

概述智能手机的迅速普及,大大的丰富了我们的娱乐生活。现在大家都喜欢晚上睡觉前玩会儿手机,但是应用的日间模式往往亮度太大,对眼睛有较为严重的伤害。因此,如今的应用往往开发了日间和夜间两种模式供用户切换使用,

智能手机的迅速普及,大大的丰富了我们的娱乐生活。现在大家都喜欢晚上睡觉前玩会儿手机,但是应用的日间模式往往亮度太大,对眼睛有较为严重的伤害。因此,如今的应用往往开发了 日间和夜间 两种模式供用户切换使用,那日间和夜间模式切换究竟是怎样实现的呢?

在文字类的App上面基本上都会涉及到夜间模式、就是能够根据不同的设定、呈现不同风格的界面给用户、而且晚上看着不伤眼睛、实现方式也就是所谓的换肤(主题切换)、对于夜间模式的实现网上流传了很多种方式、这里先分享一个方法给大家、通过设置背景为透明的方法、降低屏幕的亮度与色度。


夜间模式代码

public voID night() {  WindowManager.LayoutParams params = new WindowManager.LayoutParams(      LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT,LayoutParams.TYPE_APPliCATION,WindowManager.LayoutParams.FLAG_NOT_touchABLE          | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);  params.gravity=Gravity.BottOM;  params.y=10;  if(myVIEw==null){    myVIEw=new TextVIEw(this);    myVIEw.setBackgroundcolor(0x80000000);  }  mWindowManager.addVIEw(myVIEw,params);  Editor edit = skinSp.edit();  edit.putString("skin",NIGHT);  edit.commit();}

白天模式

public voID day(){  if(myVIEw!=null){    mWindowManager.removeVIEw(myVIEw);    Editor edit = skinSp.edit();    edit.putString("skin",DAY);    edit.commit();  }}

下面通过实例 *** 作来详细展示如何进行AndroID主题切换中的白天/夜间模式。

上述两幅图片,正是两款App的夜间模式效果,所以,依据这个功能,来看看切换主题到底是怎么实现的(当然现在github有好多Plugintheme开源插件,很多时候可以使用这些插件,不过我并不想讲怎么用那些插件,正所谓会用轮子还不如会造轮子)。

关于更换主题和换肤

这里提到是做换主题功能,当然与之类似的就是换肤,换肤现在比较流行的是采用插件化动态加载技术来实现的,这样可以起到热插拔作用,需要皮肤时候用户自主的在网上下载便是了,不用皮肤时便删了皮肤插件包而不会影响宿主App的功能,这样就不必把一大堆皮肤图片放在本地而增加apk的大小,关于用插件化实现换肤功能这仅仅是插件化技术的冰山一角,关于插件化技术更多的作用,可以看看360前两天开源的 Droidplugin插件框架、OpenAltas框架、还有主席的DL框架。

好了,言归正传,现在我们需要实现的是主题切换功能,关于主题切换其实是切换整个App的颜色风格、排版风格、字体风格等,其中并不会有过多的图片资源的切换,如有过多的图片的更换那就是换肤的功能了。
现在我们要实现夜间/白天模式的切换功能,如下效果图:


@H_403_57@

可以看到上面的效果正是夜间和白天两种模式的切换功能,切换至夜间模式时整个App的背景色、字体颜色、按钮颜色、标题栏颜色等全部需要切为夜间模式的颜色,当切回白天模式又切回原来的颜色,来看看怎么做的?

实现主题切换

首先就是需要在app中准备两套主题:

白天主题

<resources>  <style name="Daytheme" parent="theme.AppCompat.light.DarkActionbar">    <!-- Customize your theme here. -->    <item name="colorPrimary">#03A9F4</item>    <item name="androID:textcolorPrimary">#ffffff</item>    <item name="androID:windowBackground">@color/background_material_light</item>    <item name="colorAccent">#00BCD4</item>    <item name="colorControlnormal">#00BCD4</item>    <item name="TitleStyle">@style/DayTitleStyle</item>    <item name="contentStyle">@style/DayContentStyle</item>    <item name="buttonBg">#2196F3</item>    <item name="buttonTextcolor">#ffffff</item>    <item name="checkTextcolor">#2196F3</item>    <item name="switchTextcolor">#2196F3</item>  </style>  <style name="DayTitleStyle">    <item name="androID:textcolor">#212121</item>    <item name="androID:textSize">20sp</item>    <item name="androID:layout_margin">8dp</item>  </style>  <style name="DayContentStyle">    <item name="androID:textcolor">#9C27B0</item>    <item name="androID:textSize">16sp</item>    <item name="androID:layout_margin">16dp</item>    <item name="androID:maxlines">10</item>  </style></resources>

夜间主题

<resources>  <style name="Nighttheme" parent="theme.AppCompat.light.DarkActionbar">    <!-- Customize your theme here. -->    <item name="colorPrimary">#00796B</item>    <item name="androID:textcolorPrimary">#212121</item>    <item name="androID:windowBackground">@color/background_material_dark</item>    <item name="colorAccent">#00796B</item>    <item name="colorControlnormal">#212121</item>    <item name="TitleStyle">@style/NightTitleStyle</item>    <item name="contentStyle">@style/NightContentStyle</item>    <item name="buttonBg">#00796B</item>    <item name="buttonTextcolor">#9E9E9E</item>    <item name="checkTextcolor">#212121</item>    <item name="switchTextcolor">#212121</item>  </style>  <style name="NightTitleStyle">    <item name="androID:textcolor">#212121</item>    <item name="androID:textSize">20sp</item>    <item name="androID:layout_margin">8dp</item>  </style>  <style name="NightContentStyle">    <item name="androID:textcolor">#212121</item>    <item name="androID:textSize">16sp</item>    <item name="androID:layout_margin">16dp</item>    <item name="androID:maxlines">10</item>  </style></resources>

上面这两套主题中,各个属性定义完全一模一样,不一样的只是属性的值,其中在Daytheme和Nighttheme的style中有这么一段代码:

<item name="TitleStyle">@style/DayTitleStyle</item><item name="contentStyle">@style/DayContentStyle</item><item name="buttonBg">#2196F3</item><item name="buttonTextcolor">#ffffff</item><item name="checkTextcolor">#2196F3</item><item name="switchTextcolor">#2196F3</item>

正常情况下style中是不存在这些属性的,它们这些是自定义属性,主要是用来控制某些控件或者布局的属性,它们的定义在attr文件中:

<?xml version="1.0" enCoding="utf-8"?><resources>  <attr name="contentStyle" format="reference"/>  <attr name="TitleStyle" format="reference"/>  <attr name="buttonBg" format="reference|color"/>  <attr name="buttonTextcolor" format="reference|color"/>  <attr name="checkTextcolor" format="reference|color"/>  <attr name="switchTextcolor" format="reference|color"/></resources>

然后在布局中引用即可:

<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:tools="http://schemas.androID.com/tools"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  androID:orIEntation="vertical"  tools:context=".MainActivity">  <TextVIEw        androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="@string/Title" />  <TextVIEw        androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="@string/hello_world" />  <CheckBox    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="CheckBox"    androID:textcolor="?attr/checkTextcolor" />  <CheckBox    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="CheckBox"    androID:textcolor="?attr/checkTextcolor" />  <Switch    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="Switch"    androID:textcolor="?attr/switchTextcolor" />  <button    androID:ID="@+ID/btn_setting"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:text="设置"    androID:background="?attr/buttonBg"    androID:textcolor="?attr/buttonTextcolor" /></linearLayout>

最后在整个App主题的style中使用它们就ok了。这样做有什么好处呢?我们都知道App设置主题时候都是设置一个style,而App中某些控件或者布局的背景或者style样式需要和整个主题样式不同时,这时候可以通过设置个自定义属性,通过在App的style中给与自定义属性不同的值来达到目的。

切换主题

好了,有了两套主题了,接下来是通过代码来进行控制主题间的切换了,控制主题的切换其实就是通过settheme(R.style.*);来设置不同的style从而达到界面风格的变换,不过这个方法settheme()只在setContentVIEw()方法前设置才有效,所以如果你想在其它地方调用这个方法来切换主题那是肯定不行的,所以这里有两个难点?

1、怎么处理当前的设置界面在切换主题后同时切换主题风格

2、怎么处理之前已经打开的界面让他们切换主题风格

这里我给出的答案是:

1、在当前切换主题的设置界面使用Activity.recreate()方法,该方法的作用就是当当前Activity的配置发生变化时,调用这个方法可以把当前Activity实例销毁并重新创建出一个Activity实例。如此可见通过这个方法可以很容易的解决问题一,因为它会重新创建一个新的Activity实例。

2、这里我使用的方法是通过设置Intent的Flag来达到更新之前Activity的效果,通过设置mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);让它清除之前的Activity再创建一个新的Activity,这样当返回之前的界面就可以更新主题了。【注】如果有多个界面可以通过设置主界面MainActivity的launchMode为singleTask,在返回主界面时候清除其它界面来更新主题

对于上面的方法(如有更好的方法欢迎告知,万分感谢!)

代码实现

最后再贴下代码:
通过一个主题设置工具类设置主题,在每个Activity的setContentVIEw()方法之前设置主题:
设置主题工具类:

public class themeChangeUtil {  public static boolean isChange = false;  public static voID changetheme(Activity activity){    if(isChange){      activity.settheme(R.style.Nighttheme);    }  }}

设置界面:

public class Changetheme extends AppCompatActivity {  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    themeChangeUtil.changetheme(this);    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_change);    button mChangeBtn = (button) findVIEwByID(R.ID.btn_change);    mChangeBtn.setonClickListener(new VIEw.OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        if (themeChangeUtil.isChange) {          themeChangeUtil.isChange = false;        } else {          themeChangeUtil.isChange = true;        }        Changetheme.this.recreate();//重新创建当前Activity实例      }    });  }  @OverrIDe  public voID onBackpressed() {    super.onBackpressed();    Intent mIntent = new Intent(this,MainActivity.class);    mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);    startActivity(mIntent);    finish();  }}

主界面:

public class MainActivity extends AppCompatActivity {  @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    themeChangeUtil.changetheme(this);    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    button mSettingBtn = (button) findVIEwByID(R.ID.btn_setting);    mSettingBtn.setonClickListener(new VIEw.OnClickListener() {      @OverrIDe      public voID onClick(VIEw v) {        MainActivity.this.startActivity(new Intent(MainActivity.this,Changetheme.class));      }    });  }}

以上就是AndroID主题切换中的白天/夜间模式的详细过程及代码,一开始先给大家简单的展示了代码,而后详细的介绍过程及代码,需要的朋友参考。

总结

以上是内存溢出为你收集整理的Android主题切换之探究白天和夜间模式全部内容,希望文章能够帮你解决Android主题切换之探究白天和夜间模式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1148818.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存