做者:Zhujiang
, 本文經做者受權發佈,連接:https://juejin.im/post/5e95633951882573c2192501android
前言
第一次聽到暗黑模式的時候,感受好酷啊,聽着就好看(也不知道我怎麼聽出來的)。蘋果在前幾年就有暗黑模式的風聲,好像是在IOS十一、IOS12的時候就說要推出了,結果愣生生等到了IOS13暗黑模式才推出。IOS13推出到如今已經大半年了,系統應用沒得說,完美適配,三方應用也都陸續支持了暗黑模式,就連微信在前段時間的更新中也實現了暗黑模式,先來欣賞下微信的暗黑模式吧!web
![](http://static.javashuo.com/static/loading.gif)
正文
既然蘋果實現了暗黑模式,那麼安卓確定不能落下啊,因此在安卓10(Q API級別29)中支持了暗黑模式,不過官方的叫法爲Dark theme,怎麼翻譯都行,先來看一下官方對暗黑模式的定義吧:編程
![](http://static.javashuo.com/static/loading.gif)
這裏就不一行行翻譯了,主要來講一下暗黑模式的好處吧:微信
-
手機的屏幕目前大部分都已經升級成了OLED屏幕(固然還有一部分手機仍是LCD屏幕),OLED屏幕顯示黑色的時候不會發光,能夠大大減少功耗。 -
提升了弱視用戶和對強光敏感的用戶的可見性。 -
使任何人在昏暗的環境中都更容易使用設備。
怎樣開啓暗黑模式就很少說了,手機廠商不一樣,開啓方式不一樣,各大手機廠商魔改的系統有時候真的找不到在哪設置,那就百度一下吧。編程語言
設置暗黑主題
爲了支持Dark主題,必須將應用的主題設置爲繼承自DayNight主題(res/values/styles.xml
):編輯器
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
還可使用 MaterialComponents的深色主題:ide
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
這會將應用程序的主主題與系統控制的夜間模式標誌相關聯,併爲應用程序提供默認的深色主題(啓用時)。當系統的主題切換時,應用也會隨之切換主題。post
「這就完了?」字體
「對啊,主題就設置完了。」動畫
「那我若是想要自定義主題呢?」
你們平常開發中確定會有這種需求,官方定義的主題不徹底能知足咱們的需求,這時候就須要來自定義主題了,谷歌也爲咱們想到了這一點。普通模式下我們不須要動,該怎麼寫怎麼寫,而後在res下再新建一個values-night的文件夾,而後把你自定義的放進去,name起成和styles.xml中對應的主題名稱就能夠了。來看一下吧:
![](http://static.javashuo.com/static/loading.gif)
這樣設置完就OK了。
「不對啊,這只是主題變了,那個人Activity的背景、字體的顏色、圖片等等該怎麼辦呢?」
「彆着急,下面就要說了。」
這裏必定要注意,主題和樣式應避免在淺色主題下使用硬編碼的顏色或圖標,應該使用主題屬性(首選)或夜間限定的資源。來了解下兩個最重要的主題屬性吧:
-
?android:attr/textColorPrimary
這是一種通用的文本顏色。淺色主題爲近黑色,深色主題爲近白。它包含禁用狀態。 -
?attr/colorControlNormal
通用圖標顏色。它包含禁用狀態。
固然確定不是必需要使用上面官方提供的兩個主題屬性,想自定義就自定義啊!眼睛尖的可能已經看見了,上面的圖片中的values-night
中除了放有style.xml
外還有colors.xml
,對,沒錯,我們只要把顏色信息放入到colors.xml
中而後根據需求寫上兩個顏色就行了。
但仍是建議使用Material Design Components,由於它的顏色主題系統 (例如主題屬性?attr/colorSurface和?attr/colorOnSurface)
能夠輕鬆訪問合適的顏色。
「大哥,背景顏色和字體顏色我知道怎麼改了,圖片呢?圖片咋辦啊!」
「來了來了,猴急猴急的!」
圖片設置其實和顏色差很少,也是兩套資源,好比你的drawable
文件夾下有一張aaa.jpg
的圖片,你想在暗黑模式下還稱另一張圖片,那麼你就能夠新建一個drawable-night
的文件夾,在裏面放上你的另一張圖片就好了,注意, 圖片名稱必定要和drawable中的對應。同理,drawable-xhdpi
、drawable-xxhdpi
就是再建兩個文件夾:drawable-night-xhdpi
、drawable-night-xxhdpi
,而後放入對應圖片就好了。
「什麼?你想看一下效果?那好吧,如你所願,這真的是你,要是別人我都不讓他看。。。。」
![](http://static.javashuo.com/static/loading.gif)
怎麼樣,效果還能夠吧?
應用內修改主題
「我還想本身主動切換,不想隨着系統換才換」
「來,你過來,你還想幹啥,說,來來來,說吧」
「我就想本身主動設置是否跟隨系統切換主題。。。我看好多應用都有這個功能」
哎,既然你發自心裏的問了,那我就大發慈悲的告訴你:固然能夠喲!
通常來講應用都會有幾個選項供你選擇,分別是:普通模式、暗黑模式、跟隨系統,對吧?谷歌也給了咱們這幾個選項,能夠直接進行設置:
-
LightMODE_NIGHT_NO -
黑暗- MODE_NIGHT_YES -
由省電模式設定- MODE_NIGHT_AUTO_BATTERY -
系統預設- MODE_NIGHT_FOLLOW_SYSTEM
我們剛纔所說的就是Light、黑暗和系統預設,省電模式這裏就不寫, 若是有需求能夠進行實驗。
切換主題的方法也很簡單,直接調用下面方法就行:
AppCompatDelegate.setDefaultNightMode()
就一行代碼就好了,參數須要傳入上面的四種模式之一。
來吧,那就寫一下代碼吧,按照上面的要求寫三個按鈕,分別來實現普通模式、暗黑模式和系統模式吧:
override fun onClick(v: View) {
when(v.id){
R.id.btnLight ->{
setDefaultNightMode(MODE_NIGHT_NO)
}
R.id.btnDark ->{
setDefaultNightMode(MODE_NIGHT_YES)
}
R.id.btnDefault ->{
setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM)
}
}
}
這個代碼應該不須要解釋了,上面解釋的已經夠多了。來看一下實現效果吧:
![](http://static.javashuo.com/static/loading.gif)
配置變動
「大哥,我又想了下,若是有的頁面正在播放視頻,我想要延遲配置更改該怎麼辦啊?」
「來,你過來小兄弟,逗着大哥玩呢?這一每天的!」
來吧,有需求就得有實現,谷歌大大已經爲咱們都想好了,應用能夠經過聲明每一個Activity能夠處理uiMode 配置更改來處理Dark主題自己的實現:
<activity
android:name=".MyActivity"
android:configChanges="uiMode" />
當Activity聲明它處理配置更改時,onConfigurationChanged()
將在主題更改時調用其方法。
要檢查當前主題是什麼,應用能夠運行以下代碼:
val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
Configuration.UI_MODE_NIGHT_NO -> {} // 夜間模式未啓用,咱們正在使用淺色主題
Configuration.UI_MODE_NIGHT_YES -> {} // 夜間模式啓用,咱們使用的是深色主題
}
總結
文章到這裏基本結束了,谷歌用行動告訴咱們儘可能不要硬編碼,出來混都是要還的,硬編碼一時爽,一直硬編碼一直爽,哈哈哈。喜歡的點贊+關注啊!
---END---
![](http://static.javashuo.com/static/loading.gif)
本文分享自微信公衆號 - 技術最TOP(Tech-Android)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。