Understanding of custom attributes

Simply record the understanding gained. . . .

Knowledge points

Insert picture description here

Through knowledge points, we can also know that this section mainly revolves around TypedArray to understand attributes to obtain relevant knowledge points.

Custom attribute process understanding diagram

Insert picture description here

Get custom attributes in custom view

1. TypedArray object acquisition

(1) Common methods

obtainAttributes(AttributeSet set, int[] attrs) 

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

Reason: Several construction methods must be rewritten when customizing the view. At this time, the AttributeSet parameter has been provided, and it can be passed directly.
1. In fact, AttributeSet is the collection of attributes and attribute values ​​of the view you use.
2. Attrs is actually a collection of attribute resource ids (usually we pass parameters through styleable)

2. Understanding of AttributeSet

(1) Understanding

The key and value of all attributes defined in the layout file can be obtained through AttributeSet.

(2) Thinking

Can it be obtained through AttributeSet? What about TypedArray? In fact, AttributeSet will have some drawbacks. For example, you use the method of quoting string for the text attribute of textview. At this time, you should pay attention when using AttributeSet to get the value. And it can be easily obtained using TypedArray provided by Android.

3. Understanding of the four overloads of obtainStyledAttributes

(1) Method

//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. Need an array of id, id of type StyleableRes
3. Need AttributeSet and array of id, id of type StyleableRes.
ps: What exactly is @StyleableRes? In fact, you get the second parameter passed by TypedArray (context.obtainStyledAttributes(attrs, R.styleable.SettingView)) to generate the id array at the bottom layer, which is generated by the system.

(2) In-depth method

It is found that the bottom layer of these four methods is to call the getTheme().obtainStyledAttributes method of the Context class. In-depth discovery and call the obtainStyledAttributes method of the Resources class, and finally the obtainStyledAttributes of the implementation class ResourcesImpl of the Resources class for processing

//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;
            }
        }
           

Get custom attributes in custom view

This is the first time I saw it in the default dividing line implementation class provided by 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) Common methods

When you first encounter it, you will find that it is not in a custom view. AttributeSet is definitely not available, and it can only be obtained by TypedArray.

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

Generally use the first one, just pass the resource id array.

Several ways to obtain custom attribute values

There are three common ways to obtain:
  • attrs.getAttributeXXXValue (namespace, custom attribute name)
  • for (int i=0;i<attrs.getAttributeCount();i++) get from the attribute collection
  • Use TypedArray (recommended)

end

Recommended reading:
Android in-depth understanding of custom attributes in Android

Reference:
Deep understanding of Android custom attr Style styleable and its application

Reference practice:
Customize the general SettingView of the app setting interface on the market in actual combat

Guess you like

Origin blog.csdn.net/qq_38350635/article/details/101034131