obtainStyledAttributes
可以看到android 给自定义View提供了好几个构造函数。相对应的也有好几个obtainStyledAttributes
重载方法
obtainStyledAttributes(@StyleableRes int[] attrs)
:从系统主题theme中获取attrs中的属性obtainStyledAttributes(@StyleRes int resid, @StyleableRes int[] attrs)
throws Resources.NotFoundException:从资源文件定义的style中读取属性,可能抛出运行时异常obtainStyledAttributes(AttributeSet set, @StyleableRes int[] attrs)
:从layout设置的属性集中获取attrs中的属性,通常inflate布局就是使用的这个构造obtainStyledAttributes(AttributeSet set, @StyleableRes int[] attrs, @AttrRes int defStyleAttr,@StyleRes int defStyleRes)
参数说明
@StyleableRes int[] attrs
:id数组,告诉我们需要获取的属性AttributeSet set
:包含属性的集合,如android:layout_width=”match_parent”等,包含了两种来源
一种是layout中直接指定,如android:src=”@mipmap/ic_launcher”
一种是layout中的style引用,如 style=”@style/TextAppearance.AppCompat.Large”@AttrRes int defStyleAttr
:是theme 中的一个属性attr,是一个style引用。
ps:ViewPagerIndicator中style属性attr的定义;
<declare-styleable name="ViewPagerIndicator">
<!-- Style of the circle indicator. -->
<attr name="vpiCirclePageIndicatorStyle" format="reference"/>
<!-- Style of the icon indicator's views. -->
<attr name="vpiIconPageIndicatorStyle" format="reference"/>
<!-- Style of the line indicator. -->
<attr name="vpiLinePageIndicatorStyle" format="reference"/>
<!-- Style of the title indicator. -->
<attr name="vpiTitlePageIndicatorStyle" format="reference"/>
<!-- Style of the tab indicator's tabs. -->
<attr name="vpiTabPageIndicatorStyle" format="reference"/>
<!-- Style of the underline indicator. -->
<attr name="vpiUnderlinePageIndicatorStyle" format="reference"/>
</declare-styleable>
CircleIndicator中的引用
public CirclePageIndicator(Context context, AttributeSet attrs) {
//从theme中索引默认值
this(context, attrs, R.attr.vpiCirclePageIndicatorStyle);
}
public CirclePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
}
style优先级
注意:上面第三个参数,表示样式从 layout属性 -> layout中style属性 ->theme中item来进行查找。
如果此参数传入0,则表示不向Theme中搜索默认值。
@StyleRes int defStyleRes
||@StyleRes int resid
:从资源文件中定义的某个样式中读取,
仅在@AttrRes defStyleAttr = 0
或@AttrRes defStyleAttr != 0但Theme中没有为@AttrRes defStyleAttr属性
赋值时起作用。
因此可以看到在CircleIndicator中是将此参数直接传入0的,因为它不起作用
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePageIndicator, defStyle, 0);
小范围上的属性会覆盖大范围的属性,其优先级为
AttributeSet(layout.xml){style.xml指定
优先于 android: 指定
} > defStyleAttr(@AttrRes主题可配置样式attr) > defStyleRes(@StyleRes独立样式style) > (主题中直接指定的样式item)