这个是在在做一个换肤功能时遇到的问题。

对于换肤,网上都有示例,可以从别的皮肤安装包中读取所要的资源,前提是你必须先持有这个资源的引用名称,像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 skinViewList = new ArrayList (); private void scanViewGroup(ViewGroup group, List 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等等属性,从而扩大换肤的范围。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android工程换背景图片,android换肤功能 如何动态获取控件中背景图片的资源id?相关推荐

  1. 【MFC】动态加载Picture Control控件中的图片

    [MFC]动态加载Picture Control控件中的图片 前言 方法1:CBrush 方法2:SetBitmap 参考链接 方法3:重写MyPictureControl 前言 在MFC窗体中,我们 ...

  2. android EditText 控件中加入图片(非背景图片)

    效果如下: 只需要 利用EditTExt的 drawableLest 属性 <EditText android:id="@+id/Edit_user"android:layo ...

  3. 利用OpenCV在picture控件中显示图片

    (1)首先要保证OpenCV的头文件已包含进程序,并且已在工程中正确lib等文件目录. (2)添加一个picture控件 (3)在对话框初始化函数(或者某按钮响应函数)中 CWnd* pwnd = G ...

  4. C# WinForm解决Panel控件中的图片刷新时会闪烁的问题

    最近在项目开发过程中,使用Panel控件显示座位背景图,在分屏切换时,发现背景图会闪烁.在同事的帮助下,通过以下方法解决了: 新建一个类,继承Panel控件类,然后开启该控件的双重辅助缓冲区,禁止擦除 ...

  5. iapp保存图片控件中的图片,iapp编程怎么添加图片

    iapp怎么制作软件,求完整入门教程! 进入到iapp,该软件点击进入到首页点击创建1是从共享中心导入大神的源码2是就是给你的软件起个名字,比如说你这个软件叫什么名字啊? 3是选择软件的图标4是选择男 ...

  6. DataGridView控件中显示图片及其注意事项 【z】

    windows Forms编程里面有一个DataGridView控件,它不光是可以显示数据,可以显示按钮,复选框,甚至还可以显示图片.这些图片可以来自于数据库(用二进制的方式存储的),也可以来自文件系 ...

  7. Android开发之动态添加控件

    动态添加TextView控件: 一:创建一个Android project项目 activity_main.xml文件: 1.用两个LinearLayout布局分别包裹一对TextView,EditT ...

  8. vc picture控件载入背景图,随控件大小改变

    在mfc里,想要在Picture控件中载入一张图片有两种方法:静态的和动态的.静态的方法就是图片先载入资源(.rc)文件中,拥有一个唯一的ID:动态的方法就是制定图片的路径名即可. 当然这样的方法网上 ...

  9. C#设置label(标签)控件的背景颜色为透明

    C#学习笔记:设置label(标签)控件的背景颜色为透明 有时候,我们需要将控件的背景颜色设定为透明,比如说label(标签)控件.那么,如何将控件的背景颜色设定为透明?是不是只要将控件的BackCo ...

最新文章

  1. blfs(systemv版本)学习笔记-使用apache创建简单的网页服务器
  2. JAVA _构造函数
  3. 自底向上的web数据操作指南
  4. DL之DNN:利用MultiLayerNet模型【6*100+ReLU+SGD,weight_decay】对Mnist数据集训练来抑制过拟合
  5. 现代php中文版,现代PHP
  6. 方法区元空间实现之jdk7和8字符串常量池、运行时常量池、静态变量到底在哪?
  7. 怎么做一个定时消息提醒_如何用Nodejs编写一个定时消息提醒应用?
  8. Magento调试 - 页面空白,打开错误报告的方法
  9. c语言翁凯中程序,程序设计入门——C语言(翁凯老师)(基础部分)(总结)...
  10. 数学之路(3)-机器学习(3)-机器学习算法-欧氏距离(3)
  11. C语言编程乐高,ROBOLAB 2.9 编程指南第五章乐高机器人-基础小实验
  12. xp系统怎样添加桌面计算机,如何为XP系统计算机设置桌面
  13. 多元统计分析最短距离法_多元统计分析方法
  14. html企业微信发送消息,通过企业微信API接口发送消息到个人微信
  15. 定义Student类,该类中有Sting name和int age两个属性,该类实现Comparable接口,实现根据学生姓名和年龄排序,该类重写toString()输出学生的姓名和年龄。
  16. AM5SE-IS防孤岛保护装置如何解决分布式光伏发电过程中的影响?
  17. ESP32 HTTP Client接口使用
  18. 基于安卓的视频遥控小车——红外遥控部分
  19. 【PAT甲级 单源最短路径】1087 All Roads Lead to Rome (30 分)
  20. 华中农业大学算法实验课答案

热门文章

  1. bzoj 3261 最大异或和【可持久化trie】
  2. 在使用静态构造函数的时候应该注意几点
  3. github网页链接
  4. 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)
  5. 第一百八十四节,jQuery-UI,验证注册表单
  6. JS判断日期是否在同一个星期内,和同一个月内
  7. Query Designer中的特征限制(Characteristic Restrictions)、缺省值(Default Values)、自由特性(Free Characteristics)...
  8. 安卓中资源ID的问题
  9. 81、通过secureCRT连接虚拟机时几种连接方式的不同
  10. transmute[推荐小软件]