android 自定义xml属性

618 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

android 自定义xml属性解析

我们自定义View时,基本都会有以下几个构造函数,最终都会调用MyCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)。如果是存在自定义属性,就需要用到context.obtainStyledAttributes,这也是自定义属性的最重要的你1那就·u函数。
public class MyCardView extends FrameLayout {

    public MyCardView(@NonNull Context context) {
//这里不要填super,因为FrameLayout调用this时就不会调用MyCardView的构造函数了,只会调用他自己的构造函数了,所以就不会执行到MyCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)。
        this(context,null);
    }

    public MyCardView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public MyCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        TypedArray a= context.obtainStyledAttributes(attrs, R.styleable.MyCardView,defStyleAttr,R.style.custom);
        System.out.println(a.getDimension(R.styleable.MyCardView_radius,2));
        System.out.println();
        a.recycle();
    }

}

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

  • set:layout文件中,该view下的属性。

    我们用debug看一下 layout

<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/design_default_color_error"
>

image.png

我们可以看到下面显示一共有3个属性

TypedArray的作用就是获取属性值,相较AttributeSet来说,即使是引用也可以获取到引用之后的值。

  • defStyleAttr:一般不用这个(设为0就好)

  • defStyleRes:区别于defStyleAttr,当defStyleAttr为0或者defStyleAttr中也找不到默认值,就在defStyleRes指向的style中寻找。

  • attrs:要寻找的属性值(这里是我们的自定义属性styable,他会自动转为int数组)

后面就可以通过获取到的TypedArray读取属性值了。

自定义属性

新建一个xml文件,在下,添加如下自定义属性

    <declare-styleable name="MyCardView">

        <attr name="radius" format="dimension">
        </attr>
        <attr name="sticky" format="boolean"/>

    </declare-styleable>

format是该属性的数据类型 如果想给属性值起一个别名,可以这么写

<declare-styleable name="MyCardView">

    <attr name="radius" format="dimension">
        <enum name="corner" value="10"/>
    </attr>
    <attr name="sticky" format="boolean">
    </attr>>

</declare-styleable>

image.png