Android實現apk插件方式換膚
- 2019 年 10 月 14 日
- 筆記
換膚思路:
1.什麼時候換膚?
xml載入前換膚,如果xml載入後換膚,用戶將會看見換膚之前的色彩,用戶體驗不好。
2.皮膚是什麼?
皮膚就是apk,是一個資源包,包含了顏色、圖片等。
3.什麼樣的控制項應該進行換膚?
包含背景圖片的控制項,例如textView文字顏色。
4.皮膚與已安裝的資源如何匹配?
資源名字匹配
步驟:
1.xml載入前換膚,意味著需要將所需要換膚的控制項收集起來。因此要監聽xml載入的過程。
1 public class BaseActivity extends Activity { 2 3 SkinFactory skinFactory; 4 5 @Override 6 protected void onCreate(@Nullable Bundle savedInstanceState){ 7 super.onCreate(savedInstanceState); 8 9 //監聽xml生成的過程 10 skinFactory = new SkinFactory(); 11 LayoutInflaterCompat.setFactory(getLayoutInflater(),skinFactory); 12 } 13 }
2.需要換膚的控制項收集到一個容器中並且不更改自己的邏輯直接換膚(例如:不用在每個需要換膚的空間裡面加上: “ app:…… ” 自定義控制項屬性)
思考:
(1)安裝的apk的id與皮膚id是否一樣?
(2)圖片的資源、顏色資源都對應R自動生成的id
(3)皮膚包的資源id、R文件的資源id以及app里R文件的資源的id是否是一樣的?——是不一樣的
3.一個activity有多個控制項(SkinView) 一個控制項對應多個換膚屬性(SkinItem)
SkinItem來封裝這些值:
- attrName-屬性名(background)
- attrValue-屬性值id 十六進位(@color/colorPrimaryDark)
- attrType–類型(color)
- Id(R文件的id)
1 class SkinItem{ 2 // attrName background 3 String attrName; 4 5 int refId; 6 // 資源名字 @color/colorPrimaryDark 7 String attrValue; 8 // drawable color 9 String attrType; 10 11 public SkinItem(String attrName, int refId, String attrValue, String attrType) { 12 this.attrName = attrName; 13 this.refId = refId; 14 this.attrValue = attrValue; 15 this.attrType = attrType; 16 } 17 18 public String getAttrName() { 19 return attrName; 20 } 21 22 public int getRefId() { 23 return refId; 24 } 25 26 public String getAttrValue() { 27 return attrValue; 28 } 29 30 public String getAttrType() { 31 return attrType; 32 } 33 }
SkinView:
1 class SkinView{ 2 private View view; 3 private List<SkinItem> list; //收集需要換膚的集合 4 5 public SkinView(View view, List<SkinItem> list) { 6 this.view = view; 7 this.list = list; 8 } 9 }
4.收集完畢後,應用換膚 (xml載入過程中換膚)
創建SkinManager去獲得皮膚apk,app通過SkinManager獲取皮膚apk
(1)載入皮膚包(loadSkin):通過反射獲得AsserManager的addAssetpath()方法,再通過這個方法獲得皮膚apk,從而實例化skinResource;再通過PackageManager.getPackageArchiveInfo(path,PackageManager.GET_ACTIVITIES).packageName;獲得皮膚包名
(2)獲取顏色(getColor):判斷skinResource是否為空;拿到res的名字,eg:通過“colorAccent”去尋找id