Android 自定义控件之第三讲:obtainStyledAttributes 系列函数详解
在项目中开发自定义控件时,或多或少都会用到 obtainStyledAttributes(AttributeSet, int[], int, int)
或者 obtainAttributes(AttributeSet, int[])
函数,它们的主要作用是:根据传入的参数,返回一个对应的 TypedArray
,如果小伙伴还没有看过 LZ 的第二讲,那么请自行移步 Android 自定义控件之第二讲:TypedArray 详解,好了,就先扯到这里,下面开始今天内容讲解:
获取 TypedArray 对象 的函数一共四个:
1.public TypedArray obtainStyledAttributes (int[] attrs)
;
2.public TypedArray obtainStyledAttributes (int resid, int[] attrs)
;
3.public TypedArray obtainAttributes (AttributeSet set, int[] attrs)
;
4.public TypedArray obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
。
讲解之前,需要说明一点:函数 1、2、4 都是 Resources.Theme 的函数,而 3 是 Resources 的函数。
接下来,我们针对这四个函数一 一进行讲解:
1. 解析前的准备
1. 在资源文件 values 下创建文件 attrs.xml,如下:
2. 在资源文件 layout 下创建文件 activity_main.xml,如下:
2. 解析
1. obtainStyledAttributes (int[] attrs)
Google Developer 是这么解释这个函数的:
主要信息也就这么一句:
Return a TypedArray holding the values defined by Theme which are listed in attrs
它的大意是:返回一个与 attrs 中列举出的属性相关的数组,数组里面的值由 Theme 指定。从上面的概述中,我们可以知道:这个 Theme 就是关键。于是 LZ 各种试,皇天不负苦心人,谜底最终还是解开了:<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPmF0dHJzILbU06a1xMr00NTWtbHY0Ou2qNLl1NogQXBwbGljYXRpb24g1tAgYW5kcm9pZDp0aGVtZSC21NOmtcQgc3R5bGUgz8KjrNKyvs3Kx8u1o7o8L3A+DQo8cD7O0sPH1NrOqiBBcHBsaWNhdGlvbiDJ6NbD1vfM4rXEzazKsdDo0qrU2rbU06a1xNb3zOLPws6qIGF0dHJzIMno1sPP4LnYtcTK9NDUo7o8L3A+DQo8cD48c3Ryb25nPjEuIMfltaXOxLz+PC9zdHJvbmc+PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
2. styles 文件
3. 构造函数
TypedArray _TypedArray = mContext.getTheme().obtainStyledAttributes (R.styleable.MyFirstCustomerView);
应用程序运行效果如下:
what?!
这些个奇怪字符都是从哪里来的,其实 LZ 也不知道,但是打了个断点看了下,发现从 mText = _TypedArray.getString(R.styleable.MyFirstCustomerView_text);
获取数据的时候已经是这些奇怪字符了,出现问题了,当然有解决问题的办法,我们只需要在构造函数里面做如下操作:
if(!TextUtils.isEmpty(mText)){
mText = "第一种";
}
这样之后,就是我们想要的效果了:
对!就是这么个情况,搜了下貌似没有人遇到上面的问题,关键这个函数本来就很少有人用,所以等后面吧,也许未来的某一天,LZ 灵机一动,就知道这个问题的答案了,哈哈~,开玩笑~
不知道小伙伴有没有发现,我们在 Layout 布局文件中也为 attrs 对应的属性赋值了,其实简单的分析下就可以知道:无论我们有没有在 Layout 布局文件中为 attrs 对应属性赋值,这些值都不会起作用,因为这些值是从 Theme 中获取的,不相信的小伙伴可以自己试下,答案肯定和 LZ 分析的一样。
2. obtainStyledAttributes (int resid, int[] attrs)
Google Developer 是这么解释这个函数的:
细心的朋友一定会发现,其实这个函数的解释和上面的那个差不多。没错!格式几乎一样,因此我们只需要仿照上面的例子,找出这句话里面的关键字即可:
Return a TypedArray holding the values defined by the style resource resid which are listed in attrs
这句话的大意是:返回一个与 attrs 中列举出的属性相关的数组,数组里面的值由 样式属性resid 指定。其实这句话已经很明确了,因此我们就不做过多的赘述,直接上 Demo:
1. 清单文件
2. styles 文件
3. 构造函数
TypedArray _TypedArray = mContext.getTheme().obtainStyledAttributes (R.style.MyFirstCustomerViewStyle_1,R.styleable.MyFirstCustomerView);
应用程序运行效果如下:
对,就是这么简单!
同上个函数一样,因为 attrs 的属性都是 style 文件中获取的,因此无论是否在 Layout 布局文件中为 attrs 添加属性,这些值都不会起作用。
3. obtainAttributes (AttributeSet set, int[] attrs)
Google Developer 是这么解释这个函数的:
相信在自定义控件的时候,应该有好多小伙伴和 LZ 一样喜欢用这个函数吧。
同上面两个函数一样,也是一句话:
Retrieve a set of basic attribute values from an AttributeSet, not performing styling of them using a theme and/or style resources.
这句话的大意是:从 AttributeSet 中获取 attrs 对应的属性值,不为这些属性值设置样式。
考虑到很多小伙伴经常使用这个函数,因此,直接上 Demo:
1. XML 布局文件