android換膚功能 如何動(dòng)態(tài)獲取控件中背景圖片的資源id?
這個(gè)是在在做一個(gè)換膚功能時(shí)遇到的問(wèn)題。
對(duì)于換膚,網(wǎng)上都有示例,可以從別的皮膚安裝包中讀取所要的資源,前提是你必須先持有這個(gè)資源的引用名稱,像R.drawable.background(喂,這不是廢話嘛)。這個(gè)換膚的方案原理就是,自身應(yīng)用的資源名稱是R.drawable.background,那皮膚包中應(yīng)該也是這個(gè)名稱,然后通過(guò)這個(gè)名稱獲取該資源在皮膚包中的具體id,代碼:
//先獲取本地資源引用名稱,type name是R.drawable.background中的"drawable",entry name是"background" String resTypeName = getContext().getResources().getResourceTypeName(id); String resEntryName = getContext().getResources().getResourceEntryName(id); //然后創(chuàng)建皮膚包所在應(yīng)用的Context Context apk = getContext().createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY) //然后就是獲取皮膚包中的資源id了 int drawavleId = apk.getResources().getIdentifier(resEntryName, resTypeName, apk.getPackageName());
這個(gè)換膚方案中,每個(gè)Activity在切換皮膚時(shí),需要遍歷整個(gè)layout,判斷控件如果id中包含“skin”的字符,意味這個(gè)控件是需要換膚的控件,這個(gè)控件的id可以先保存下來(lái)。
遍歷視圖的代碼
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()); } } }
問(wèn)題來(lái)了,本地應(yīng)用中,你持有一個(gè)控件,比如Button,它的id可以直接調(diào)用button.getId()方法獲取,但是它的背景圖片background呢,我們可以調(diào)用button.getBackground()方法獲取其對(duì)象,但是卻沒(méi)有方法可以獲取這個(gè)資源圖片的引用名稱,也就無(wú)法得到它的具體id了。后面想到的方案就是,在每次Activity初始化的時(shí)候,我們事先遍歷每一個(gè)控件的屬性集AttributeSet,有需要換膚的控件,將其android:background這個(gè)屬性的值保存下來(lái),為此,需要重載Activity的onCreateView(String name, Context context, AttributeSet attrs)方法,這個(gè)方法我的理解是在Activity中每個(gè)控件(包括LinearLayout、TextView、Button等等)初始化前會(huì)調(diào)用,我也打了log,進(jìn)行了驗(yàn)證,其中attrs參數(shù)就是該控件的屬性集,這就是我們需要的,代碼:
//先判斷前面掃描的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); } }
有了這個(gè)backgroundId,就能獲取該資源的引用名稱R.drawable.background,然后我們就能通過(guò)名稱從其他包獲取對(duì)應(yīng)的資源文件了,從而可以執(zhí)行換膚操作。而且,通過(guò)這個(gè)方法,不只可以獲取圖片資源的id,也能獲取字符串如R.string.title,字體顏色如R.color.red,字體大小如R.dimens.text_size_small等等屬性,從而擴(kuò)大換膚的范圍。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
listview與SQLite結(jié)合實(shí)現(xiàn)記事本功能
這篇文章主要為大家詳細(xì)介紹了listview與SQLite結(jié)合實(shí)現(xiàn)記事本功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android中手機(jī)震動(dòng)的設(shè)置(Vibrator)的步驟簡(jiǎn)要說(shuō)明
Android中手機(jī)震動(dòng)的設(shè)置(Vibrator)的步驟,很詳細(xì),感興趣的朋友可以了解下哦2013-01-01ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo
這篇文章主要為大家介紹了ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11Android編程實(shí)現(xiàn)分頁(yè)加載ListView功能示例
這篇文章主要介紹了Android編程實(shí)現(xiàn)分頁(yè)加載ListView功能,結(jié)合實(shí)例形式分析了listview分頁(yè)加載的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-02-02Android音樂(lè)播放器簡(jiǎn)單實(shí)現(xiàn)案例
我們平時(shí)長(zhǎng)時(shí)間打代碼的時(shí)候肯定會(huì)感到疲憊和乏味,這個(gè)時(shí)候一邊播放自己喜歡的音樂(lè),一邊繼續(xù)打代碼,心情自然也愉快很多。音樂(lè)帶給人的聽(tīng)覺(jué)享受是無(wú)可比擬的,動(dòng)聽(tīng)的音樂(lè)可以愉悅?cè)说纳硇模屓烁臃e極地去熱愛(ài)生活,這篇文章主要介紹了Android音樂(lè)播放器簡(jiǎn)單實(shí)現(xiàn)案例2022-12-12Android UI實(shí)現(xiàn)多行文本折疊展開(kāi)效果
這篇文章主要為大家詳細(xì)介紹了Android UI實(shí)現(xiàn)多行文本折疊展開(kāi)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android 菜單欄DIY實(shí)現(xiàn)效果詳解
這篇文章主要為大家介紹了Android 菜單欄DIY實(shí)現(xiàn)效果詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09