博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不通过R类获取自定义样式资源ID数组
阅读量:4029 次
发布时间:2019-05-24

本文共 2854 字,大约阅读时间需要 9 分钟。

昨天遇到并解决的需求,以此文记录,供遇到同类问题的同仁参考!

需求描述

不引用R类获取到自定义样式的值(资源id数组),如下是R.java中某个自定义样式的值

public static final int[] LoadingView = { 0x7f0200ac, 0x7f0200c5, 0x7f0200cd, 0x7f0200ce, 0x7f0200cf };

即如下代码如示,在自定义view组件中,获取自定义样式的值时不能使用R.styleable

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.drop_down_list_attr);mIsOnBottomStyle = ta.getBoolean(R.styleable.drop_down_list_attr_isOnBottomStyle, false);mIsAutoLoadOnBottom = ta.getBoolean(R.styleable.drop_down_list_attr_isAutoLoadOnBottom, false);

解决方案

通过资源字符串获取资源id的方式获取自定义样式各个项的资源id值

示例代码如下

public MyLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        /**        int a = R.attr.loadding_color;        int b = R.attr.ring_style;        int styleAttrId[] = R.styleable.LoadingView;        a == styleAttrId[0]        b == styleAttrId[2]            **/        Resources res = context.getResources();        int styleAttrIdArray[] = new int[2]; //LoadingView的属性项的个数,示例中仅有两个        styleAttrIdArray[0] =  res.getIdentifier("loadding_color", "attr", context.getPackageName());        styleAttrIdArray[1] =  res.getIdentifier("ring_style", "attr", context.getPackageName());        //TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoadingView, 0, 0);        TypedArray a = context.obtainStyledAttributes(attrs, styleAttrIdArray, 0, 0);        //如下的R.styleable.LoadingView_loadding_color,LoadingView_ring_style是索引常量,在R.java类中查看替换即可        setColor(a.getInt(R.styleable.LoadingView_loadding_color, -12871201));        setRingStyle(a.getInt(R.styleable.LoadingView_ring_style, 0));        //setColor, setRingStyle这里是自定义方法    }

技术原理

关键点:自定义样式所有属性项的值(资源ID数组)其实都是存放在资源类R的内部attr类的!

如下是某个自定义样式

生成的R类,对应字段如下

这里写图片描述
对应的某个属性项在R类的attr区,如下所示
这里写图片描述

解决方案二

有时候方案一会失效,原因是“打包”后的资源文件中自定义属性的排序与你“看到的”R文件中的排序不一致,解决方案是对自定义属性id值的数据做排序,并动态获取自定义属性的索引值,代码如下所示

int id1 = res.getIdentifier("loadding_color", "attr", context.getPackageName()); int id2 = res.getIdentifier("ring_style", "attr", context.getPackageName()); int styleAttrIdArray[] = new int[2]; //LoadingView的属性项的个数,示例中仅有两个 styleAttrIdArray[0] = id1;  styleAttrIdArray[1] = id2;  //排序一下 Arrays.sort(styleAttrIdArray); int ringStyleAttrIndex = Arrays.binarySearch(styleAttrIdArray, id1); int loaddingAttrIndex = Arrays.binarySearch(styleAttrIdArray, id2); //TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LoadingView, 0, 0); TypedArray a = context.obtainStyledAttributes(attrs, styleAttrIdArray, 0, 0); //如下的R.styleable.LoadingView_loadding_color,LoadingView_ring_style是索引常量,在R.java类中查看替换即可 setColor(a.getInt(loaddingAttrIndex, -12871201)); setRingStyle(a.getInt(ringStyleAttrIndex, 0)); //setColor, setRingStyle这里是自定义方法
你可能感兴趣的文章
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>
Java中数字转大写货币(支持到千亿)
查看>>
Java.nio
查看>>
函数模版类模版和偏特化泛化的总结
查看>>
VMware Workstation Pro虚拟机不可用解决方法
查看>>
最简单的使用redis自带程序实现c程序远程访问redis服务
查看>>
redis学习总结-- 内部数据 字符串 链表 字典 跳跃表
查看>>
iOS 对象序列化与反序列化
查看>>
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>