Android 之夜間模式(多主題)的實現思路
引言
夜間模式其實屬於多主題切換的一種,不過是最麻煩的一種。因為在夜間模式下不僅要切換主色調,次要色調等等,還要覆蓋一些特殊的顏色,因為在夜間模式下總不能什麼都是黑的把,那不得醜死-。-,所以當你夜間模式完成後,你的App對於日後多主題的擴充套件就可以輕鬆勝任了。
實現思路
多數App由於歷史原因當對其進行夜間模式的功能改造時,工作量是比較大的,所以在真正開始著手實現前,我們還是應該先明確夜間模式(多主題)到底有多少實現的思路以及它們的優劣,這樣才可以有效的避免專案延期的情況出現。
-
自定義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中的識別問題,該方法就能大大減少重複程式碼了。
-
重寫getResource方法
這是第三方微部落格戶端Fuubo所採用的方式。重新Acticity和Application的getResource方法,統一同一顏色的是呼叫名字,對於不同主題在getRsource中進行判斷並返回對應的顏色值。
這樣做的好處是你不用定義很多份的drawable,selector之類的xml檔案,你的所有顏色都將在getRsource中通過R.color中判斷並替換,省去很多工作,而且基本可以不改動你以前的程式碼。
當然壞處也是顯而易見的,當你的App複雜時所有的替換邏輯都集中在getRsource()中將會顯得十分的臃腫,並且你無法使用theme中的系統屬性,因為theme中的屬性並不是通過Activity的getResource()進行載入的,所以例如系統的popMenu就無法改變其背景色等屬性,都需要你自定義實現了。
切換方式
談到夜間模式或多主題切換,就不得不說另一個問題主題的切換方式。
-
重啟Activity。
這是最常用的切換方式,也是最暴力的解決方式,哈哈。
當然需要注意的是一定要在 super.onCreate(savedInstanceState);之前呼叫,不然會發生很多的意外問題-,- 。
至於重啟的方式有很多,可以直接Intent.FLAG_ACTIVITY_CLEAR_TOP,再啟動一個新的 Activity。或者finish自己再重新startActivity,或者最簡單的直接呼叫onRecreate()即可(相當於發生了 configuration change),然後再加上一個過渡的動畫效果,這就根據自己App的情況自行選擇了。
-
重新整理所有控制元件。
其實現的思路是在自定義屬性的基礎上,再自定義每個控制元件,並將與主題顏色相關的屬性全部封裝在控制元件中,然後通過一個統一的介面,每當主題發生改變時,對當前Activity從根View開始進行遞迴遍歷重新整理,而對於listview則是清空RecycleBin中的所有child view,這樣就等於是強行重新整理了整個listview。
這種方式最大的優點就是可以不重啟Activity就可以更換Activity的主題顏色,大大優化了使用者的體驗。當然缺點也很明顯,因為如果你的App不是一開始就這麼做,那麼改造的工作量更加巨大(因為還要實現自定義屬性=。=)。
目前github已有人實現了這種思路的換主題框架, 傳送門 。
換膚
上面並沒有討論換主題的另一個方向:換膚。因為個人覺得簡單換膚其實與換主題色的區別並不是特別大,只需要新增換膚apk的下載,並將其資源載入到app中替換即可,網上有很多的實現思路,再這就不在傫述。而對於複雜的換膚,即如天天動聽一樣不僅可以更換主題顏色,資原始檔,還可以更換 Layout佈局!這。。。增加的工作量就不是多一點點的問題了(和以上討論的情況相比),所以暫不討論-。-。
結語
以上是關於Android切換主題的一點心得,希望對您有些許幫助,有不正確的地方歡迎指出討論,如果您有其他的一些實現思路,也歡迎補充,謝謝。
相關文章
- Android夜間模式(多主題)探索Android模式
- Android 實現切換主題皮膚功能(類似於眾多app中的 夜間模式,主題包等)AndroidAPP模式
- 外掛化實現Android多主題功能原理剖析Android
- Android 動態佈局實現多主題切換Android
- App 多區域皮膚(主題)的實現APP
- MySQL多主一從的實現MySql
- 前端另一種多語言的實現思路前端
- [android]MonkeyRunner-andrec實現思路Android
- Android 設定主題實現點選波紋效果Android
- Android換膚實現技術思路總結Android
- 多執行緒-多執行緒方式2的思路及程式碼實現執行緒
- JS實現單例模式的多種方案JS單例模式
- 程式介面多模式顯示的實現 (轉)模式
- MySQL叢集之 主從複製 主主複製 一主多從 多主一叢 實現方式MySql
- Android上實現MVP模式的途徑AndroidMVP模式
- Android:Fragment懶載入的實現以及自己的封裝思路AndroidFragment封裝
- 請教Hibernate的多主鍵操作如何實現?
- android 自定義ScrollView實現背景圖片伸縮的實現程式碼及思路AndroidView
- Android Fragment實現按鈕間的切換AndroidFragment
- Android 7.0中的多視窗實現解析Android
- c#winform主題實現的一個方法C#ORM
- Toast 元件實現思路AST元件
- promise基本實現思路Promise
- 題目:2.兩數相加 解題思路及Java實現Java
- Android實現多語言so easyAndroid
- Redis 哨兵模式實現主從故障互切換Redis模式
- 現有 Vue.js 專案快速實現多語言切換的一種思路Vue.js
- 實現Vue專案主題切換Vue
- Sass應用之實現主題切換
- golang 實現多型的賦值問題Golang多型賦值
- 直播商城原始碼,實現系統的日間/夜間模式切換原始碼模式
- Android 時間軸的實現(RecyclerView更簡單)AndroidView
- 一種跳板機的實現思路
- JavaScript依賴注入的實現思路JavaScript依賴注入
- android全屏去掉title欄的多種實現方法Android
- 快速實現android版抖音主介面的心得Android
- weex 原始碼解析(一) — 整體實現思路(Android視角)原始碼Android
- weex 原始碼解析(一) -- 整體實現思路(Android視角)原始碼Android