国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android換膚功能 如何動態獲取控件中背景圖片的資源id?

2019-12-12 05:28:09
字體:
來源:轉載
供稿:網友

這個是在在做一個換膚功能時遇到的問題。  

對于換膚,網上都有示例,可以從別的皮膚安裝包中讀取所要的資源,前提是你必須先持有這個資源的引用名稱,像R.drawable.background(喂,這不是廢話嘛)。這個換膚的方案原理就是,自身應用的資源名稱是R.drawable.background,那皮膚包中應該也是這個名稱,然后通過這個名稱獲取該資源在皮膚包中的具體id,代碼:

  //先獲取本地資源引用名稱,type name是R.drawable.background中的"drawable",entry name是"background"  String resTypeName = getContext().getResources().getResourceTypeName(id);  String resEntryName = getContext().getResources().getResourceEntryName(id);  //然后創建皮膚包所在應用的Context  Context apk = getContext().createPackageContext(packageName,      Context.CONTEXT_IGNORE_SECURITY)  //然后就是獲取皮膚包中的資源id了  int drawavleId = apk.getResources().getIdentifier(resEntryName, resTypeName,      apk.getPackageName());  

這個換膚方案中,每個Activity在切換皮膚時,需要遍歷整個layout,判斷控件如果id中包含“skin”的字符,意味這個控件是需要換膚的控件,這個控件的id可以先保存下來。

遍歷視圖的代碼 

  private List<Integer> skinViewList = new ArrayList<Integer> ();  private void scanViewGroup(ViewGroup group, List<Integer> skinViewList, Resources res) {    //first we need check if this ViewGroup have a background    if(group.getId() != View.NO_ID        && res.getResourceEntryName(group.getId()).contains(SKIN_PATTERN)        && !skinViewList.contains(group)) {      skinViewList.add(group.getId());    }    //second check its child view    View child;    for(int i = 0; i < group.getChildCount(); i++) {      child = group.getChildAt(i);      if(child instanceof ViewGroup) {        scanViewGroup((ViewGroup)child, skinViewList, res);      } else if(child.getId() == View.NO_ID) {        return;      } else {        int viewId = child.getId();        String entryName = res.getResourceEntryName(viewId);        Log("scanViewGroup(), entryName of this childView : " + entryName);        if(entryName.contains(SKIN_PATTERN) && !skinViewList.contains(child))          skinViewList.add(child.getId());      }    }  }

問題來了,本地應用中,你持有一個控件,比如Button,它的id可以直接調用button.getId()方法獲取,但是它的背景圖片background呢,我們可以調用button.getBackground()方法獲取其對象,但是卻沒有方法可以獲取這個資源圖片的引用名稱,也就無法得到它的具體id了。后面想到的方案就是,在每次Activity初始化的時候,我們事先遍歷每一個控件的屬性集AttributeSet,有需要換膚的控件,將其android:background這個屬性的值保存下來,為此,需要重載Activity的onCreateView(String name, Context context, AttributeSet attrs)方法,這個方法我的理解是在Activity中每個控件(包括LinearLayout、TextView、Button等等)初始化前會調用,我也打了log,進行了驗證,其中attrs參數就是該控件的屬性集,這就是我們需要的,代碼: 

    //先判斷前面掃描的skinViewList是否為空,不為空意味著有控件需要換膚    if(skinViewList != null && skinViewList.size() > 0) {      int viewId = -1, backgroundId = -1;      for(int i = 0; i < attrs.getAttributeCount(); i++) {        if(attrs.getAttributeName(i).equals("id")) {          viewId = attrs.getAttributeResourceValue(i, -1);        }        if(attrs.getAttributeName(i).equals("background")) {          backgroundId = attrs.getAttributeResourceValue(i, -1);        }      }      //check if background drawable need save      if(viewId != -1 && backgroundId != -1 &&          drawableIdList != null && !drawableIdList.containsKey(viewId)) {        drawableIdList.put(viewId, backgroundId);        Log("add to drawableIdList, viewId = " + viewId            + ", backgroundId = " + backgroundId);      }    }

有了這個backgroundId,就能獲取該資源的引用名稱R.drawable.background,然后我們就能通過名稱從其他包獲取對應的資源文件了,從而可以執行換膚操作。而且,通過這個方法,不只可以獲取圖片資源的id,也能獲取字符串如R.string.title,字體顏色如R.color.red,字體大小如R.dimens.text_size_small等等屬性,從而擴大換膚的范圍。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁晋县| 外汇| 甘南县| 南漳县| 临湘市| 鹿邑县| 汽车| 金门县| 潼关县| 望都县| 大港区| 麻江县| 襄樊市| 美姑县| 汉川市| 游戏| 泾阳县| 娱乐| 宁陵县| 舟曲县| 綦江县| 长春市| 广汉市| 阳曲县| 宁安市| 合肥市| 广昌县| 吉安市| 武陟县| 玉林市| 胶州市| 板桥市| 同心县| 田东县| 凌海市| 辰溪县| 阿克| 大同县| 北安市| 林甸县| 保德县|