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


    1. 夜间模式

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

    2. 我根据网上的资料 以及自己代码亲测,总结如下两种方法:

    (1)降低屏幕亮度

    (2)替换theme

    3. 夜间模式之 降低屏幕亮度

    (1)创建一个Android工程,命名为"夜间模式_利用屏幕亮度(App)",如下:

    (2)首先我们来到主布局之中,如下:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical"
     6     tools:context="com.himi.screenlight.MainActivity" >
     7 
     8     <Button
     9         android:onClick="SetAppBrightness"
    10         android:layout_width="match_parent"
    11         android:layout_height="wrap_content"
    12         android:text="设置应用程序内亮度" />
    13 
    14 </LinearLayout>

    (3)来到MainActivity,如下:

     1 package com.himi.screenlight;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 import android.view.View;
     6 import android.view.WindowManager;
     7 /**
     8  * 
     9  * 降低屏幕的亮度
    10  * 该方法缺点是不能将亮度值保存起来,可以通过SharedPreferences来保存数据。
    11  * @author hebao
    12  *
    13  */
    14 public class MainActivity extends Activity {
    15     
    16     private static int init = 1;
    17 
    18     @Override
    19     protected void onCreate(Bundle savedInstanceState) {
    20         super.onCreate(savedInstanceState);
    21         setContentView(R.layout.activity_main);
    22     }
    23     
    24     
    25     
    26     /****************设置应用程序的亮度*****************/
    27     public void SetAppBrightness(View view) {
    28          switch(init % 5){
    29          case 0:
    30              setBrightness(50);
    31            
    32              break;
    33          case 1:
    34              setBrightness(100);
    35             
    36              break;
    37          case 2:
    38              setBrightness(150);
    39              
    40              break;
    41          case 3:
    42              setBrightness(200);
    43            
    44              break;
    45          case 4:
    46              setBrightness(255);
    47            
    48              break;
    49              
    50          }
    51          init ++;
    52     }
    53     
    54 
    55     public void setBrightness(int brightness) {
    56         WindowManager.LayoutParams lp = getWindow().getAttributes();
    57         lp.screenBrightness = brightness / 255.0f; 
    58         getWindow().setAttributes(lp);
    59     }
    60     
    61     
    62     
    63 
    64 }

    运行到手机上是可以改变屏幕亮度的,这种方法实际开发中使用得不多。

    上面关于设置屏幕亮度的核心代码如下:

         WindowManager.LayoutParams lp = getWindow().getAttributes();

         lp.screenBrightness = brightness / 255.0f;

         getWindow().setAttributes(lp);

    4. 夜间模式之 替换theme

    (1)创建一个Android工程,命名为"夜间模式_利用theme",如下:

    (2)在工程 res/values/attrs.xml 文件中,增加自定义属性

    1 <?xml version="1.0" encoding="utf-8"?>  
    2 <resources>  
    3     <declare-styleable name="NightMode">  
    4         <attr name="day_night_background" format="color" />  
    5         <attr name="day_night_text_color" format="color" />  
    6     </declare-styleable>  
    7 </resources>  

    (3)在工程res/values/colors.xml文件中,增加自定义属性用到的颜色

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <resources>
    3     <color name="night_color">#000000</color>
    4     <color name="light_color">#ffffff</color>
    5 </resources>

    (4)在工程 res/values/styles.xml 文件中,增加"AppSunTheme" 和"AppNightTheme",parent 均为AppBaseTheme. 同时在这两个styles中一一对应的加入attrs.xml文件中的属性

     1 <resources>
     2 
     3     <!--
     4         Base application theme, dependent on API level. This theme is replaced
     5         by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
     6     -->
     7     <style name="AppBaseTheme" parent="android:Theme.Light">
     8         <!--
     9             Theme customizations available in newer API levels can go in
    10             res/values-vXX/styles.xml, while customizations related to
    11             backward-compatibility can go here.
    12         -->
    13     </style>
    14 
    15     <!-- Application theme. -->
    16     <style name="AppTheme" parent="AppBaseTheme">
    17         <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    18     </style>
    19     
    20     <!-- 自定义的 Application theme. -->  
    21    <style name="AppSunTheme" parent="AppBaseTheme">  
    22        <item name="day_night_background">@color/light_color</item>  
    23        <item name="day_night_text_color">@color/night_color</item>  
    24    </style>  
    25   
    26    <style name="AppNightTheme" parent="AppBaseTheme">  
    27        <item name="day_night_background">@color/night_color</item>  
    28        <item name="day_night_text_color">@color/light_color</item>  
    29    </style>  
    30     
    31 
    32 </resources>

    (5)来到主布局文件之中,将主布局activity_main.xml中需要根据主题改变的元素的background 和 color 设为自定义attrs中的属性

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:background="?attr/day_night_background"
     6     android:paddingBottom="@dimen/activity_vertical_margin"
     7     android:paddingLeft="@dimen/activity_horizontal_margin"
     8     android:paddingRight="@dimen/activity_horizontal_margin"
     9     android:paddingTop="@dimen/activity_vertical_margin"
    10     tools:context=".MainActivity" >
    11 
    12     <Button
    13         android:id="@+id/btn_theme"
    14         android:layout_width="match_parent"
    15         android:layout_height="wrap_content"
    16         android:layout_alignLeft="@+id/night"
    17         android:layout_below="@+id/night"
    18         android:layout_marginTop="28dp"
    19         android:text="使用Theme实现夜间模式"
    20         android:textColor="?attr/day_night_text_color" />
    21 
    22 </RelativeLayout>

    (6)在工程中加入NightModeUtils类来配置应用主题。因为这里要改变整个APP的主题,所以传给NightModeUtils的Context应该是Application的Context

     1 package com.himi.screen;
     2 
     3 import android.app.Activity;
     4 import android.content.Context;
     5 import android.content.Intent;
     6 import android.content.SharedPreferences;
     7 import android.view.View;
     8 import android.widget.TextView;
     9 
    10 public class NightModeUtils {
    11     public final static int THEME_SUN = 1;
    12 
    13     public final static int THEME_NIGHT = 2;
    14 
    15     /**
    16      * Set the theme of the Activity, and restart it by creating a new Activity
    17      * of the same type.
    18      */
    19     public static void changeToTheme(Activity activity) {
    20         int theme1=getDayNightMode(activity);
    21         int theme =( theme1 == THEME_SUN ? THEME_NIGHT : THEME_SUN);
    22         setDayNightMode(activity, theme);
    23 
    24         activity.finish();
    25         activity.startActivity(new Intent(activity, activity.getClass()));
    26     }
    27 
    28     /** Set the theme of the activity, according to the configuration. */
    29     public static void onActivityCreateSetTheme(Activity activity) {
    30         int theme = getDayNightMode(activity);
    31         switch (theme) {
    32             case THEME_SUN:
    33                 activity.setTheme(R.style.AppSunTheme);
    34                 break;
    35             case THEME_NIGHT:
    36                 activity.setTheme(R.style.AppNightTheme);
    37                 break;
    38             default:
    39                 break;
    40         }
    41     }
    42 
    43     public static void setBackGroundColor(Context context, View view, int theme) {
    44         int color = context.getResources().getColor(
    45                 theme == THEME_SUN ? R.color.light_color : R.color.night_color);
    46         view.setBackgroundColor(color);
    47     }
    48 
    49     public static void setTextColor(Context context, View view, int theme) {
    50         int color = context.getResources().getColor(
    51                 theme == THEME_SUN ? R.color.night_color : R.color.light_color);
    52         TextView textView = (TextView)view;
    53         textView.setTextColor(color);
    54     }
    55 
    56     public static int getSwitchDayNightMode(Context context) {
    57         int mode = getDayNightMode(context);
    58         return mode == THEME_SUN ? THEME_NIGHT : THEME_SUN;
    59     }
    60     //设置theme属性值存入xml文件之中  
    61     public static void setDayNightMode(Context context, int mode) {
    62         SharedPreferences sharedPreferences = getSharedPreferences(context);
    63         SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
    64         sharedPreferencesEditor.putInt("SUN_NIGHT_MODE", mode);
    65         sharedPreferencesEditor.apply();
    66     }
    67     //获取xml文件中theme属性值
    68     public static int getDayNightMode(Context context) {
    69         SharedPreferences sharedPreferences = getSharedPreferences(context);
    70         return sharedPreferences.getInt("SUN_NIGHT_MODE", THEME_SUN);
    71     }
    72     //设置xml文件 
    73     private static SharedPreferences getSharedPreferences(Context context) {
    74         return context.getSharedPreferences("NightModeDemo", Context.MODE_APPEND);
    75     }
    76 }



    (7) 在每个Activity中增加调用nightModeUtils类的设置主题方法,注意要加在setContentView方法之前

    setTheme方法只能在onCreate方法中实现,所以如果要改变当前Activity的注意要将当前Activity先finish再重新启动Activity

     1 package com.himi.screen;
     2 
     3 import android.app.Activity;
     4 import android.content.Context;
     5 import android.content.Intent;
     6 import android.os.Bundle;
     7 import android.view.View;
     8 import android.view.View.OnClickListener;
     9 import android.widget.Button;
    10 
    11 public class MainActivity extends Activity {
    12     
    13     private Button btn_theme;
    14 
    15     @Override
    16     protected void onCreate(Bundle savedInstanceState) {
    17         super.onCreate(savedInstanceState);
    18        // 设置启动时默认theme     
    19         NightModeUtils.onActivityCreateSetTheme(this);
    20         setContentView(R.layout.activity_main);
    21         
    22         btn_theme = (Button) findViewById(R.id.btn_theme);
    23         
    24         btn_theme.setOnClickListener(new OnClickListener() {
    25             
    26             @Override
    27             public void onClick(View v) {
    28                 // 获取当前theme            
    29                 int theme = NightModeUtils.getDayNightMode(MainActivity.this);
    30                 
    31                 Context context = getApplicationContext();
    32                 
    33                 if (theme == NightModeUtils.THEME_SUN)
    34                     NightModeUtils.setDayNightMode(context,
    35                             NightModeUtils.THEME_NIGHT);
    36                 else
    37                     NightModeUtils.setDayNightMode(context,
    38                             NightModeUtils.THEME_SUN);
    39                 
    40                 // 注意改过主题后一定要,把activity finish在重开一遍,因为更改主题只能在oncreat中进行
    41                 finish();
    42                 startActivity(new Intent(MainActivity.this, MainActivity.this.getClass()));
    43                 
    44             }
    45         });
    46     }
    47 
    48     
    49 }

     注意的是:当我们替换主题的时候,我们需要finish掉旧Activity,重新使用startActivity开启新Activity,这是因为我们只是替换主题属性,界面并没有重新绘制,需要Activity重新渲染界面,所以需要根据新的属性,重新绘制Activity

    (8)将Mainfest配置文件中Application 的theme设为默认的AppSunTheme:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.himi.screen"
     4     android:versionCode="1"
     5     android:versionName="1.0" >
     6 
     7     <uses-sdk
     8         android:minSdkVersion="15"
     9         android:targetSdkVersion="21" />
    10 
    11     <application
    12         android:allowBackup="true"
    13         android:icon="@drawable/ic_launcher"
    14         android:label="@string/app_name"
    15         android:theme="@style/AppSunTheme" >
    16         <activity
    17             android:name=".MainActivity"
    18             android:label="@string/app_name" >
    19             <intent-filter>
    20                 <action android:name="android.intent.action.MAIN" />
    21 
    22                 <category android:name="android.intent.category.LAUNCHER" />
    23             </intent-filter>
    24         </activity>
    25     </application>
    26 
    27 </manifest>

    上面设置了应用程序初始状态的主题样式为AppSunTheme

    总结如下:

    (9)部署程序到手机上测试,如下:

    本文示例代码下载地址http://download.csdn.net/detail/hebao5201314/9591112

  • 相关阅读:
    aodquery,clientdataset数据控件之间的速度区别
    centos防火墙相关
    centos安装jdk,精简
    delphi 操作excel复制区域功能呢
    centos安装redis,最靠谱的教程
    图像识别,借助百度云,上传图片实现逻辑
    LinkedHashmap和HashMap对比以及说明
    Windows环境下Zookeeper安装和使用
    你不知道的JavaScript--Item1 严格模式
    jQuery学习之旅 Item2 选择器【二】
  • 原文地址:https://www.cnblogs.com/hebao0514/p/5723063.html
Copyright © 2020-2023  润新知