Android 之夜間模式(多主題)的實現

jopen 9年前發布 | 35K 次閱讀 Android Android開發 移動開發
 

引言

夜間模式其實屬于多主題切換的一種,不過是最麻煩的一種。因為在夜間模式下不僅要切換主色調,次要色調等等,還要覆蓋一些特殊的顏色,因為在夜間模式下總不能什么都是黑的把,那不得丑死-。-,所以當你夜間模式完成后,你的App對于日后多主題的擴展就可以輕松勝任了。

實現思路

多數App由于歷史原因當對其進行夜間模式的功能改造時,工作量是比較大的,所以在真正開始著手實現前,我們還是應該先明確夜間模式(多主題)到底有多少實現的思路以及它們的優劣,這樣才可以有效的避免項目延期的情況出現。

  1. 自定義attr屬性。

    這是最基礎的方法,就是通過自定義attr屬性,在不同的theme中進行不同的實現,然后在layout和style中調用。這種方法改代碼改動量比較大,而且根據不同的主題,drawable(5.0以上不用),selector等xml文件必須要相應的定義多份,因為 android由于兼容性和自身的原因并不能在這些文件中識別attr屬性(會報type解析錯誤),當然style和theme可以直接識別使用。

    在shape,selector中不識別attr屬性我個人覺得可能是android的bug,因為5.0以上的drawable中是可以識別attr屬性的,所以理論上是可行的。若能解決在selector等xml中的識別問題,該方法就能大大減少重復代碼了。

  2. 重寫getResource方法

    這是第三方微博客戶端Fuubo所采用的方式。重新Acticity和Application的getResource方法,統一同一顏色的是調用名字,對于不同主題在getRsource中進行判斷并返回對應的顏色值。

    這樣做的好處是你不用定義很多份的drawable,selector之類的xml文件,你的所有顏色都將在getRsource中通過R.color中判斷并替換,省去很多工作,而且基本可以不改動你以前的代碼。

    當然壞處也是顯而易見的,當你的App復雜時所有的替換邏輯都集中在getRsource()中將會顯得十分的臃腫,并且你無法使用theme中的系統屬性,因為theme中的屬性并不是通過Activity的getResource()進行加載的,所以例如系統的popMenu就無法改變其背景色等屬性,都需要你自定義實現了。

切換方式

談到夜間模式或多主題切換,就不得不說另一個問題主題的切換方式。

  1. 重啟Activity。

    這是最常用的切換方式,也是最暴力的解決方式,哈哈。

    當然需要注意的是一定要在 super.onCreate(savedInstanceState);之前調用,不然會發生很多的意外問題-,- 。

    至于重啟的方式有很多,可以直接Intent.FLAG_ACTIVITY_CLEAR_TOP,再啟動一個新的 Activity。或者finish自己再重新startActivity,或者最簡單的直接調用onRecreate()即可(相當于發生了 configuration change),然后再加上一個過渡的動畫效果,這就根據自己App的情況自行選擇了。

  2. 刷新所有控件。

    其實現的思路是在自定義屬性的基礎上,再自定義每個控件,并將與主題顏色相關的屬性全部封裝在控件中,然后通過一個統一的接口,每當主題發生改變時,對當前Activity從根View開始進行遞歸遍歷刷新,而對于listview則是清空RecycleBin中的所有child view,這樣就等于是強行刷新了整個listview。

    這種方式最大的優點就是可以不重啟Activity就可以更換Activity的主題顏色,大大優化了用戶的體驗。當然缺點也很明顯,因為如果你的App不是一開始就這么做,那么改造的工作量更加巨大(因為還要實現自定義屬性=。=)。

    目前github已有人實現了這種思路的換主題框架, 傳送門

換膚

上面并沒有討論換主題的另一個方向:換膚。因為個人覺得簡單換膚其實與換主題色的區別并不是特別大,只需要添加換膚apk的下載,并將其資源加載到app中替換即可,網上有很多的實現思路,再這就不在傫述。而對于復雜的換膚,即如天天動聽一樣不僅可以更換主題顏色,資源文件,還可以更換 Layout布局!這。。。增加的工作量就不是多一點點的問題了(和以上討論的情況相比),所以暫不討論-。-。

結語

以上是關于Android切換主題的一點心得,希望對您有些許幫助,有不正確的地方歡迎指出討論,如果您有其他的一些實現思路,也歡迎補充,謝謝。

作者:XycZero

查看原文: http://www.xyczero.com/blog/article/25/ .

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!