Android實現夜間模式小結

來源:互聯網
上載者:User

標籤:手機   screen   sha   man   match   extc   文字   ble   als   

隨著APP實現的功能越來越豐富, 看小說看視頻上網等等, 如今不少人花在手機平板等移動終端上的時間越來越長了. 但手機和平板的螢幕並不像Kindle那類電紙書的水墨屏那麼耐看, 因為自發光的螢幕特性, 我們長期盯著螢幕看easy眼睛酸痛疲倦, 因此各種護目模式, 夜間模式在移動APP上得到廣泛應用, 這的確也是一個貼心的小功能. 所以這次我們探討下幾種實現方式, 一起學習總結下:


1, 利用螢幕亮度

當夜間使用手機等終端, 直接降低螢幕亮度, 能降低光線強度對眼鏡的刺激, 這也是最簡單, 也相對有效方式. 

請先加入對應許可權:

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
通過設定螢幕亮度來實現的方法, 有兩種:


1) 僅僅設定應用程式內的亮度

一般, Android裡每一個Activity相應一個可視的介面, 針對每一個Activity去設定亮度, 方法例如以下:

public static void setBrightness(Activity activity , float brightnessValue)    {        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();        if(brightnessValue > 1.0f)        {            lp.screenBrightness = 1.0f;        }        else if(brightnessValue <= 0.0f)        {               lp.screenBrightness = 0.0f;        }        else        {            lp.screenBrightness = brightnessValue;        }        activity.getWindow().setAttributes(lp);    }

這樣, 一個程式包括的全部Activity, 我們都要單獨去設定它的亮度, 雖說能夠封裝成工具類去使用, 但前提是有沒有更好的方法呢? 請看另外一種:


2) 設定手機系統的亮度(全域亮度)

這裡, 我們直接在程式的某個Activity, 比方入口Activity去設定整個手機的亮度. 因為已經設定手機全域的亮度, 那麼後面不管跳轉到哪個介面, 甚至退出程式, 手機的亮度依舊是所設定的亮度. 這樣的方法相對第一種而言算是"一勞永逸". 但這裡我們先要理清思路, 考慮好幾個點: 


開啟應用後, 擷取手機原來的亮度值並儲存它(可用於退出應用後恢複正常亮度) --->  假設手機開啟自己主動亮度調節則關閉自己主動調節, 然後設定合適的較低亮度 --->  將設定的亮度值應用到手機中  --->  最後,退出應用時利用儲存的原亮度值恢複原來亮度, 並又一次開啟手機的自己主動亮度調節.


接下來, 貼上關鍵代碼:

首先是擷取手機螢幕亮度值:

/**     * 擷取當前系統亮度     * <br>擷取失敗返回-1,擷取成功返回正常非負數<br>     * @param context     * @return     */    public static int getSystemBrightness(Context context)    {        int brightnessValue = -1;        try        {            brightnessValue = Settings.System.                    getInt(context.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS);        }        catch (Exception e)        {            e.printStackTrace();        }        return brightnessValue;    }

儲存, 直接放在SharePreference裡面就好了, 相關代碼就不寫了.

然後檢測手機是否開啟亮度自己主動調節的開關:

/**     * 是否開啟自己主動調節亮度     * @param contentResolver     * @return     */    public static boolean isAutoBrightness(ContentResolver contentResolver)    {        boolean autoBrightness = false;        try        {            autoBrightness                    = Settings.System.getInt(contentResolver ,                            Settings.System.SCREEN_BRIGHTNESS_MODE)                    == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;        }        catch (Exception e)        {            e.printStackTrace();        }        return autoBrightness;    }

假設開啟, 就關閉:

/**     * 停止自己主動調節亮度     * @param activity     */    public static void closeAutoBrightness(Activity activity)    {        Settings.System.putInt(activity.getContentResolver(),                Settings.System.SCREEN_BRIGHTNESS_MODE,                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);    }

最後還會用到開啟亮度調節:

public static void openAutoBrightness(Activity activity)    {        Settings.System.putInt(activity.getContentResolver(),                Settings.System.SCREEN_BRIGHTNESS_MODE,                Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);    }

關閉亮度調節後, 就設定亮度, 直接使用第一種方法中的相關代碼就可以. 但由於要將該亮度的設定應用到全域, 所以須要將該亮度值儲存到手機中:

/**     * 儲存全域的亮度值設定     * @param contentResolver     * @param brightnessValue 亮度值     */    public static void saveBrightness            (ContentResolver contentResolver , int brightnessValue)    {        Uri uri = android.provider.                Settings.System.getUriFor("screen_brightness");        android.provider.Settings.System.putInt(contentResolver,                "screen_brightness" , brightnessValue);        contentResolver.notifyChange(uri, null);    }

這樣, 終於效果就OK了, 即使退出當前應用, 手機依舊是所設定的較低亮度. 當然, 退出應用前應當恢複正常的亮度和設定, 於是就利用儲存的亮度值又一次設定, 然後將新的亮度值再次儲存到手機中就可以, 別忘了, 手機之前是開啟亮度自己主動調節的話, 還要又一次開啟自己主動調節.


2,自己定義Theme.(最經常使用的方法)

自己定義View, 相信非常多人都非常熟悉. 而自己定義Theme跟這個類似, 也是實現夜間模式最經常使用的方法, 由於它不止能夠實現夜間模式, 還能實現常見的主題更換功能. 這裡就不細說, 僅僅講思路. 如果我們的應用介面是白色背景, 黑色文字, 夜間模式就是黑色背景, 灰白色的文字. 這樣的夜間模式有別於第一種的調節亮度, 由於背景和內容文字能夠任意的設定顏色和透明度, 這樣的夜間模式看起來更直觀,也能夠更舒服. 

自己定義Theme利用的是, 在XML中定義要用到的背景和文字顏色屬性, 比方:

<declare-styleable name="MyThemeAttrs">        <attr name="activity_background" format="color" />        <attr name="text_color" format="color" />    </declare-styleable>

然後在style.xml中建立自己的兩個主題(Theme), 比方預設主題和夜間主題, 預設主題中給activity_background屬性設為白色, text_color屬性設為黑色, 夜間主題則分別為黑色和灰白色. 在View的layout檔案裡, 給所用的背景View, 比方某個RelativeLayout的backgroundColor屬性設為"?activity_background", TextView的textColor設為"?text_color"就可以. 當然, 因為這是Theme, 在Activity開始初始化視圖前去應用才幹生效. 因此最好自己封裝一個主題工具類, 在Activity的setContentView( ) 方法之前調用setTheme() 方法去設定主題.


3, WindowManager實現遮罩模式

這裡, 我們應當明確一個概念, 當不必深究, window(表單). Android的設計理念中, 給差點兒每一個顯示的組件都設定包括在一個window中. Activity也有它自己的window. 通過在window加入一層灰黑色有一定透明度的view, 使它看起來是螢幕變暗了, 當然實際上手機的亮度是沒有變化的, 這樣的實現, 能夠叫"遮罩", 類似相機拍照時在鏡頭套一層膜或者鏡片上去, 使呈現的效果有所不同. 可是這樣的方法, 也有不好的地方, 就是類似上面說的單獨在每一個Activity去設定它的亮度. 這裡每進入一個介面就須要又一次"套一層view"上去, 相對"一勞永逸"的方法而言, 顯得沒優勢. 那麼直接上代碼:

WindowManager manager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);        WindowManager.LayoutParams params = new WindowManager.LayoutParams(                WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT,                WindowManager.LayoutParams.TYPE_APPLICATION,                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,                PixelFormat.TRANSLUCENT);        params.gravity = Gravity.TOP;        params.y = 10;// 距離底部的距離是10像素 假設是 top 就是距離top是10像素        TextView tv = new TextView(this);        tv.setBackgroundColor(0x55000000);        manager.addView(tv,params);

代碼中, 通過WindowManager.LayoutParams的參數設定, 禁止所加入遮罩層的觸摸和聚焦. 這樣使得即使添上一層View, 也不會影響Activity視圖中的組件正常使用.


事實上上面三種方法, 放在如今來看, 都不是新的技術, 而網上我也看過非常多相關的代碼, 這裡這僅僅是放在一起做個對照和總結. 上面依據三種實現方法說了各自的特點, 綜合而言, 第一, 二種方法比較可取, 而到底選擇第一還是另外一種方法, 應該看詳細需求, 假設你的應用僅僅是簡單的要求減少亮度, 不想改動太多的代碼, 那麼第一種會比較適合; 假設希望有良好的體驗, 希望看起來更酷, 甚至還想加入其它的主題, 比方藍色, 綠色的主題等等, 那麼無疑另外一種是最好的選擇. 自己定義屬性的廣泛應用, 給我們實現更個人化的視覺效果(比方自己定義組件, 自己定義主題等)提供了便利.


Android實現夜間模式小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.