多套主題怎麼靈動換膚?APP換膚方案詳細解析!
背景需求
目前
Android APP
換膚大體可分為兩大類:
- 兩套主題的切換(比如白天/黑夜),使用一個開關按鈕進行切換。
- 多套主題線上下載並更新。
第一種的實現基本上使用設定本地
Theme
來操作,即將所有的資源打包到
APP
中,並且根據主題進行切換。 第二種不可能使用第一種的實現方式,因為將所有資源都打包到
APP
中缺乏靈活性,不利於活動的更新,並且也會使得
apk
包的體積變大。所有第二種的實現必須是支援線上下載的。
方案選擇
配合產品的需求並且能實現換膚的靈動性,我們選擇上述的第二種方案。經過之前的
Android
和
IOS
成員小組討論,統一覺得可以採用下載壓縮包,並透過解析壓縮包讀取資源進行替換。
壓縮包下載下來後怎麼讀取資源?這裡有兩種方式:
- 將下載的皮膚包進行解壓縮並且透過檔案流的方式讀取裡面的圖片資源、檔案資源。
- 將下載的皮膚包載入到
assetManager
管理器中,並透過該管理器新建一個Resource
物件,需要換膚的控制元件透過Resource
物件進行讀取資源。
第一種方式需要手動開啟檔案流,並且不同的檔案流有不同的檔案流方式,比如圖片、文字檔案等,還有不同裝置由於解析度載入的資源是不同的,如何合理地去選擇合適的資源去載入也是一個需要解決的問題。
第二種方式需要將皮膚包載入到
assetManager
管理器,
assetManager
管理器新生成的
Resource
物件和我們主工程的
Resource
物件是相同類的不同物件,可以使用我們熟悉的方式去載入資源(如
resource.getColor
,
resource.getDrawable
等)。
基於上述兩種載入資源的方式,這裡選擇第二種方式進行資源的載入與讀取。
具體實施
1、將所需的皮膚包透過網路下載到本地,這裡的皮膚包是一個
apk
檔案,為了讓
apk
包足夠小,裡面只包含資原始檔。可能有多個皮膚包,比如
theme1.skin
,
theme2.skin
......
2、透過後臺獲取需要載入的皮膚包的名字,如theme1.skin,透過呼叫AssetManager物件的addAssetPath方法並生成一個新的Resource物件,如下程式碼:
AssetManager assetManager = AssetManager.class.newInstance(); //由於addAssetPath()這個方法被隱藏掉了,所以不能直接使用物件直接訪問, //這裡使用了反射的方式,作用是將該皮膚包加入到asset管理器中 Method addAssetPath = assetManager.getClass().getMethod("addAssetPath" , String.class); addAssetPath.invoke(assetManager, skinPath); Resources skinResource = new Resources( assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
3、自定義一個
InflaterFactory
的子類,
SkinInflaterFactory
,重寫
onCreateView(View, String, Context, AttributeSet)
方法,對於需要換膚的控制元件進行屬性的解析與儲存,然後對這些換膚的控制元件去第二步的
Resource
物件中載入資源並設定到這些控制元件中。
4、在
BaseActivity
的
onCreate
方法新建
SkinInflaterFactory
物件,並將該
SkinInflateFactory
物件設定給
Activity
的
LayoutInflater
物件,如下程式碼:
protected void onCreate(@Nullable Bundle savedInstanceState) { mSkinInflaterFactory = new SkinInflaterFactory(); LayoutInflaterCompat.setFactory( getLayoutInflater(), mSkinInflaterFactory); super.onCreate(savedInstanceState); }
流程圖
其他問題
1、如何支援控制元件點選後觸發不同的業務流程?
可以透過自定義一個屬性,如
skin:click="@string/clickAction"
,主工程的
clickAction="muapp://app/testDefault"
,皮膚包裡的
clickAction="muapp://app/testClick"
,透過目前專案中的路由機制觸發不同的跳轉動作。比如說上述預設的跳轉是跳轉到主工程(
app
為
module
名)的
TestDefaultAction
(註解
actionName="testDefault"
)類的
invoke
方法中,而更改後會跳轉到主工程(
app
為
module
名)的
TestClickAction
(註解
actionName="testClick"
)類的
invoke
方法中。
2、如何支援控制元件的不同行為方式?例如不同的動畫效果等
這個問題和第一個問題的處理方式的類似的,同樣可以透過主工程和皮膚包不同的
tag
(
String
文案)處理不同的行為方式。
3、如何處理自定義
View
的換膚需求?
可以新增一個方法,將自定義View需要換膚的屬性名(如
background
),屬性值(如
background
對應的圖片的資源
ID
)傳遞到方法中,然後去皮膚包的
Resource
物件中尋找是否有相應的可替換的皮膚或者可替換的行為。
總結
看完之後有沒有掌握呢?作為一個程式設計師,要學的東西有很多,而學到的知識點,都是錢(因為技術人員大部分情況是根據你的能力來定級、來發薪水的),技多不壓身。
為了很好的生活,我們要多多學習,增加我們手裡的金錢。尤其經歷了這一疫情,我深深的感受到金錢的重要,所以,我們一定不能停下學習的腳步!
附上我的Android核心技術學習大綱,獲取相關內容來GitHub:
vx:xx13414521
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952849/viewspace-2676125/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MyEclipse更換主題皮膚Eclipse
- Flutter主題切換——讓你的APP也能一鍵換膚FlutterAPP
- App 多區域皮膚(主題)的實現APP
- Android動態換膚原理解析及實踐Android
- vue2.0-基於elementui換膚[自定義主題]VueUI
- Android 換膚指南Android
- antd原始碼解析——線上換膚功能原始碼
- pycharm怎麼換主題PyCharm
- 給你的Swagger文件換套附魔皮膚吧Swagger
- jq切換皮膚
- 主流技術之網易雲換膚方案
- win10瀏覽器皮膚怎麼更換_win10瀏覽器皮膚更換如何設定Win10瀏覽器
- [Delphi] 自帶皮膚動態切換
- 聊一聊前端換膚前端
- 換膚功能實現過程
- 說說Android動態換膚實現原理吧Android
- win10輸入法皮膚怎麼換 win10微軟輸入法皮膚如何改Win10微軟
- 寶塔皮膚切換PHP版本PHP
- Android 常用換膚方式以及原理分析Android
- antd線上換膚定製功能
- keycloak~登入皮膚動態切換的嘗試
- win10主題滑鼠無法更換怎麼辦_win10無法通過控制皮膚更改主題滑鼠指標如何解決Win10指標
- win10主題滑鼠無法更換怎麼辦_win10無法透過控制皮膚更改主題滑鼠指標如何解決Win10指標
- Android QMUI實戰:實現APP換膚功能,並自動適配手機深色模式AndroidUIAPP模式
- js效果——頁面如何讓換皮膚JS
- 微信小程式實現換膚功能微信小程式
- win10掃雷怎麼換主題 如何更換win10的掃雷主題Win10
- nvidia控制皮膚怎麼調 nvidia控制皮膚怎麼設定
- 多國家美膚方案SDK,打造全球膚色適配技術
- hexo主題更換以及怎麼寫部落格Hexo
- 一個輕量級的iOS皮膚切換方案(內附Demo)iOS
- Qt QtCharts給QChartView換膚,換背景色新增背景圖片QTView
- echarts 主題動態切換Echarts
- Flutter高階(二)——國際化與換膚Flutter
- 寶塔皮膚切換預設PHP版本PHP
- iOS換膚功能的簡單處理框架iOS框架
- Android 無縫換膚深入瞭解與使用Android
- Oracle 11g 一主多備切換方案Oracle