欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义属性相关的理解

程序员文章站 2022-05-29 17:48:47
...

简单的记录下理解收获。。。。

知识点

自定义属性相关的理解

通过知识点也可以知道本节主要围绕TypedArray来理解属性获取相关知识点。

自定义属性过程理解图

自定义属性相关的理解

自定义view中获取自定义属性

1、TypedArray对象获取

(1)常用方法

obtainAttributes(AttributeSet set, int[] attrs) 

obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)

原因:在自定义view时必须重写几个构造方法,这时AttributeSet 这个参数已经提供,直接传参即可。
1、其实AttributeSet 就是你使用的view的属性和属性值的集合。
2、attrs其实是属性资源id集合(一般我们通过styleable方式传参)

2、AttributeSet 的理解

(1)理解

通过AttributeSet可以获得布局文件中定义的所有属性的key和value.

(2)思考

通过AttributeSet 就可以获得?那还要TypedArray干嘛?其实AttributeSet 会有些弊端,比如textview的text属性你使用了引用字符串的方式,这时使用AttributeSet来获取值时要注意啦。而使用安卓提供的TypedArray可以轻易获取。

3、obtainStyledAttributes四个重载的理解

(1)方法

//1
public final TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) 
//2
public final TypedArray obtainStyledAttributes(@StyleRes int resid, @StyleableRes int[] attrs)
//3、自定义view中常用
public final TypedArray obtainStyledAttributes(AttributeSet set, @StyleableRes int[] attrs)
//4
public final TypedArray obtainStyledAttributes(
            AttributeSet set, @StyleableRes int[] attrs, @AttrRes int defStyleAttr,@StyleRes int defStyleRes)

1、需要一个id数组,id是StyleableRes 类型的
3、需要AttributeSet 和id数组,id是StyleableRes 类型的。
ps:@StyleableRes到底是啥,其实你获取TypedArray (context.obtainStyledAttributes(attrs, R.styleable.SettingView))传递的第二个参数底层就生成了id数组,系统生成的。

(2)方法深入

发现这四个方法底层都是调用Context类的getTheme().obtainStyledAttributes方法。再深入发现又调用了Resources类的obtainStyledAttributes方法,最终是Resources类的实现类ResourcesImpl的obtainStyledAttributes进行处理

//ResourcesImpl.java
   TypedArray obtainStyledAttributes(@NonNull Resources.Theme wrapper,
                AttributeSet set,
                @StyleableRes int[] attrs,
                @AttrRes int defStyleAttr,
                @StyleRes int defStyleRes) {
            synchronized (mKey) {
                final int len = attrs.length;
                final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);

                // XXX note that for now we only work with compiled XML files.
                // To support generic XML files we will need to manually parse
                // out the attributes from the XML file (applying type information
                // contained in the resources and such).
                final XmlBlock.Parser parser = (XmlBlock.Parser) set;
                mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
                        array.mDataAddress, array.mIndicesAddress);
                array.mTheme = wrapper;
                array.mXml = parser;
                return array;
            }
        }
           

自定义view中获取自定义属性

这个第一次是在RecyclerView提供的默认分割线实现类中看到


public class DividerItemDecoration extends ItemDecoration {
    ...
    ...
    private static final int[] ATTRS = new int[]{16843284}; // id 数组,16843284为某资源id值
    ...
    ...


    public DividerItemDecoration(Context context, int orientation) {
        TypedArray a = context.obtainStyledAttributes(ATTRS);  // 获取TypedArray对象
        this.mDivider = a.getDrawable(0);
        if (this.mDivider == null) {
            Log.w("DividerItem", "@android:attr/listDivider was not set in the theme used for this DividerItemDecoration. Please set that attribute all call setDrawable()");
        }

        a.recycle();
        this.setOrientation(orientation);
    }

(1)常用方法

初次碰到时会发现,不是自定义view中,AttributeSet肯定用不了了,只能使用TypedArray获取啦。

//1、在Context的主题中检索样式化属性信息
public final TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) 
//2、在Context的主题中检索样式化属性信息
public final TypedArray obtainStyledAttributes(@StyleRes int resid, @StyleableRes int[] attrs)

一般使用第一个,传资源id数组即可。

获取自定义属性值的几种方式

常见三种获取方式:
  • attrs.getAttributeXXXValue(命名空间,自定义属性名字)
  • for (int i=0;i<attrs.getAttributeCount();i++) 从属性集合中获取
  • 使用TypedArray(推荐)

end

建议必读:
Android 深入理解Android中的自定义属性

参考:
深入理解Android 自定义attr Style styleable以及其应用

参考实践:
自定义view实战之市场上app设置界面的通用SettingView