时间:2021-05-20
这个是在在做一个换肤功能时遇到的问题。
对于换肤,网上都有示例,可以从别的皮肤安装包中读取所要的资源,前提是你必须先持有这个资源的引用名称,像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等等属性,从而扩大换肤的范围。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
简介对与控件QPushButton中的可以使用setStyleSheet设置它背景图片。具体设置背景图片的方法有两种self.button.setStyleSh
把背景图片如常的合并,利用相似于背景坐标的方式调用局部图片位置。最大区别在于分别定义了两个无意义的标签。为满足用户的视觉追求及产品的背景图片的换肤功能,设计师难
原生JavaScript实现换肤的具体代码,供大家参考,具体内容如下原理通过点击事件,获取点击的的图片的信息,在HTML背景图片的路径改变css样式body{m
每一个网站在制作的过程中,都会设置背景图片,而且都会选择体现自己网站特色的图片作为背景图。不管是背景的颜色还是背景图片,适合网站的才是理想的。那么,如何制作
一.backstretch插件功能优化网站外观。主要用于设置页面背景图片,也可以设置html元素的背景图片。背景图片可以设置多张,在间隔时间内循环显示。注但是在