Android-0.declare-styleable的使用(自定义属性)

简单示例

Android中经常用到自定义view, 既然用了自定义view那就不得不提自定义属性。
1.首先在res 的values文件夹下新建一个attrs.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="burce">
        <attr name="mHeight" format="integer" />
        <attr name="mWidth" format="integer" />
        <attr name="mName" format="string" />
        <attr name="sex" format="enum">
            <enum name="man" value="0" />
            <enum name="woman" value="1" />
        </attr>
        <attr name="student" format="boolean" />
    </declare-styleable>
</resources>

<declare-styleable name="burce">其中的name的值随便定义一个,不要与系统的起冲突。
<attr name="mHeight" format="integer"/>:name就是自定义的属性的名字(比如系统控件的android:layout_widthformat 就是属性的类型,这里支持10种类型,常用的有stringintegerboolean等等,这次我们用到了整形,枚举和布尔。

注意:我们在自定义属性的名字的时候不能与系统的名字冲突,否则会报错

2.新建一个类继承View类,实现3个构造方法,然后获取我们自定义的属性。

public class MyView extends View {
    private static final String TAG = "MyView";
    public MyView(Context context) {
        this(context, null);
    }

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

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.burce);
        int heiget = array.getInt(R.styleable.burce_mHeight, 0);
        int width = array.getInt(R.styleable.burce_mWidth, 0);
        String name = array.getString(R.styleable.burce_mName);
        int sex = array.getInt(R.styleable.burce_sex, 0);
        boolean student = array.getBoolean(R.styleable.burce_student, true);
        array.recycle();

        Log.i(TAG, "height: " + heiget);
        Log.i(TAG, "width: " + width);
        Log.i(TAG, "name: " + name);
        Log.i(TAG, "sex: " + sex);
        Log.i(TAG, "student: " + student);
    }
}

3.在xml中使用自定义view

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <myvideo.duowan.com.mydraw.MyView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:mName="hgy"
        app:mHeight="100"
        app:mWidth="100"
        app:sex="man"
        app:student="true" />

</android.support.constraint.ConstraintLayout>

首先加入命名空间:xmlns:app="http://schemas.android.com/apk/res-auto"其中app就是自定义的命名空间。所以所有的自定义属性都加了app前缀。
运行结果:

height: 100
width: 100
name: hgy
sex: 0
student: true

format详解

1、reference :参考某一资源ID

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name="background" format="reference" />
    </declare-styleable>

(2).属性使用"@drawable/图片ID":

 app:background = "@drawable/ic_launcher_background"   

(3).属性获取:

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        Drawable drawable = array.getDrawable(R.styleable.hgy_background);

2、color:颜色值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name="textColor" format="color" />
    </declare-styleable>

(2).属性使用:

app:textColor = "#ABABAB"

(3).属性获取:

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        int color = array.getColor(R.styleable.hgy_textColor,Color.BLUE);

3、boolean:布尔值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "focusable" format="boolean" />
    </declare-styleable>

(2).属性使用:

app:focusable = "true"

(3).属性获取:

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        boolean focusable = array.getBoolean(R.styleable.hgy_focusable,false);

4、dimension:尺寸值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "layout_width" format="dimension" />
    </declare-styleable>

(2).属性使用:

app:layout_width = "20dp"

(3).属性获取:

 		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        float contentSize = array.getDimension(R.styleable.hgy_layout_width, 10);

5、float:浮点值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "fromAlpha" format="float" />
    </declare-styleable>

(2).属性使用:

app:fromAlpha = "0.723"

(3).属性获取:

		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        float alpha = array.getFloat(R.styleable.hgy_fromAlpha, 0.1f);

6、integer:整形值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "inta" format="integer"/>
    </declare-styleable>

(2).属性使用:

 app:inta = "99"

(3).属性获取:

		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        int inta = array.getInt(R.styleable.hgy_inta, 0);

7、string:字符串

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "apiKey" format = "string" />
    </declare-styleable>

(2).属性使用:

app:apiKey = "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"

(3).属性获取:

 		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        String str = array.getString(R.styleable.hgy_apiKey);

8、fraction:百分数

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "pivotX" format = "fraction" />
    </declare-styleable>

(2).属性使用:

 app:pivotX = "49%"

(3).属性获取:

 		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        float fraction = array.getFraction(R.styleable.hgy_pivotX, 1, 1, 0.f);// fraction为0.49

9、enum:枚举值

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name="orientation">
            <enum name="horizontal" value="0" />
            <enum name="vertical" value="1" />
        </attr>
    </declare-styleable>

(2).属性使用:

app:orientation = "vertical"

(3).属性获取:

		 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        int iEnum = array.getInt(R.styleable.hgy_orientation, 0);// 结果为1

10、flag:位或运算

(1).属性定义:

    <declare-styleable name="hgy">
        <attr name="windowSoftInputMode">
            <flag name = "stateUnspecified" value = "0" />
            <flag name = "stateUnchanged" value = "1" />
            <flag name = "stateHidden" value = "2" />
            <flag name = "stateAlwaysHidden" value = "3" />
            <flag name = "stateVisible" value = "4" />
            <flag name = "stateAlwaysVisible" value = "5" />
            <flag name = "adjustUnspecified" value = "0x00" />
            <flag name = "adjustResize" value = "0x10" />
            <flag name = "adjustPan" value = "0x20" />
            <flag name = "adjustNothing" value = "0x30" />
        </attr>
    </declare-styleable>

(2).属性使用:

app:windowSoftInputMode = "stateUnspecified|stateUnchanged|stateHidden"

(3).属性获取:

   		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        int iflag = array.getInt(R.styleable.hgy_windowSoftInputMode, 0);

11、直接使用系统属性

比如系统提供了一个属性叫做:android:text,那么我们可以直接使用
(1).属性定义:

    <declare-styleable name="hgy">
        <attr name="text"/>
    </declare-styleable>

注意,这里我们是使用已经定义好的属性,不需要去添加format属性(注意声明和使用的区别,差别就是有没有format)。
也不要写成 <attr name="android:text"/>,因为:是转义字符

(2).属性使用:

    app:text = "@string/app_name"

(3).属性获取:

 		TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.hgy);
        String str = array.getString(R.styleable.hgy_text);

注意

属性定义时可以指定多种类型值。
(1).属性定义:

    <declare-styleable name="hgy">
        <attr name = "background" format = "reference|color" />
    </declare-styleable>

(2).属性使用:

app:background = "@drawable/ic_launcher_background"

 app:background = "#FF00FF"

都不会报错。

AttributeSet与TypedArray

AttributeSet中保存了该View中声明的所有的属性,外面可以通过它去获取(自定义的)属性。
例如:

    <declare-styleable name="hgy">
        <attr name = "background" format = "reference" />
        <attr name = "apiKey" format = "string" />
    </declare-styleable>
    <myvideo.duowan.com.mydraw.MyView
        android:layout_width="100dp"
        android:layout_height="200dp"
        app:background = "@drawable/ic_launcher_background"
        app:apiKey = "abcde"
        />
    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        int count = attrs.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String attrName = attrs.getAttributeName(i);
            String attrVal = attrs.getAttributeValue(i);
            Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal + "\n");
        }

运行结果:

attrName = layout_width , attrVal = 100.0dip
    attrName = layout_height , attrVal = 200.0dip
    attrName = apiKey , attrVal = abcde
    attrName = background , attrVal = @2131099733

发现了什么?通过AttributeSet的确可以获得所有的值,但如果是引用都变成了@+数字的字符串。而用上面的TypedArray可以快速的获取到Drawable对象。也就是TypedArray简化了这个过程。

参考
https://www.jianshu.com/p/fbb5d6dc3a88
https://www.jianshu.com/p/2c566331a71d
https://blog.csdn.net/lmj623565791/article/details/45022631

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值