文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

android换肤功能 如何动态获取控件中背景图片的资源id?

2022-06-06 07:42

关注

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

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

您可能感兴趣的文章:Android 换肤技术资料整理Android应用开发中实现apk皮肤文件换肤的思路分析分析Android App中内置换肤功能的实现方式Android编程实现换肤功能实例Android实现换肤的两种思路分析android使用SkinManager实现换肤功能的示例


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯