美文网首页
Andorid 自定义 View - 自定义属性基础

Andorid 自定义 View - 自定义属性基础

作者: teletian | 来源:发表于2022-07-09 21:42 被阅读0次

    当我们自定义 View 的时候,至少要定义两个构造函数。

    public CustomView(Context context) {
        this(context, null);
    }
    
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs); 
        init(context, attrs);
    }
    

    第二个构造函数中的参数 attrs 可以获取在 xml 中添加的属性的值。
    系统已经给我们定义了以下属性,可以在 sdk/platforms/android-xx/data/res/values/attrs.xml 中找到。我们也可以自定义属性。

    怎么自定义属性?

    1. 在 res/values 下创建 attrs.xml 文件
    2. 添加如下内容
    <resources>
        <declare-styleable name="CustomTextView">
            <attr name="text" format="string" />
        </declare-styleable>
    </resources>
    

    declare-styleable 定义属性分组,名称一般和自定义 View 的名称一样。在 R 文件中就会生成 styleable 类。里面包含所有属性。

     public static final class styleable {
        public static final int[] CustomTextView = { 2130903853 };
        
        public static final int CustomTextView_text = 0;
      }
    

    attr 定义或者声明属性。注意,这边有两种方式:

    • 定义:后面有 format 的就是定义。
    • 声明:后面没有 format 的就是声明。比如:<attr name="android:text"/>。当属性已经在别的地方定义的时候,不能重复定义,否则会报错。
    1. 在 xml 中使用属性
    <com.smaple.CustomTextView 
      android:layout_width="wrap_content"
      android:layout_heidht="wrap_content"
      app:text = "Hello World!"
    />
    
    1. 在 Java 中获取属性值
    private void init(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
        String text = ta.getString(R.styleable.CustomTextView_text);
        // 回收
        ta.recycle();  
    }
    

    Attributeset 就是一个属性集合,内部是一个 XML 解析器,最后解析成 key-value 的形式。

    Java 中获取系统属性值

    如果要在 Java 中获取系统的属性值,必须也要在 attrs.xml 中对应的 View 下声明。

    <resources>
        <declare-styleable name="CustomTextView">
            <attr name="text" format="string" />
            <attr name="android:layout_height" />
        </declare-styleable>
    </resources>
    

    声明完了就可以在 Java 中获取了

    int height = ta.getDimensionPixelSize(R.styleable.CustomTextView_android_layout_height, 0)
    

    format 类型

    format 解释
    integer 整型值
    float 浮点值
    boolean 布尔值
    string 字符串。比如 "hello"、R.string.hello
    enum 枚举
    fraction 百分数。只能是 xx%
    flag 位或运算
    dimension 尺寸值。比如 10px、10dp、R.dimen.xx
    color 颜色值。比如 #FFFFFF、R.color.white
    reference 资源 ID。比如 R.drawable.id

    例子:
    attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CustomView">
            <attr name="attr_int" format="integer" />
            <attr name="attr_float" format="float" />
            <attr name="attr_bool" format="boolean" />
            <attr name="attr_string" format="string" />
            <attr name="attr_enum">
                <enum name="type_1" value="0" />
                <enum name="type_2" value="1" />
            </attr>
            <attr name="attr_fraction" format="fraction" />
            <attr name="attr_flag">
                <flag name="top" value="0x1" />
                <flag name="left" value="0x2" />
                <flag name="right" value="0x3" />
                <flag name="bottom" value="0x4" />
            </attr>
            <attr name="attr_dimension" format="dimension" />
            <attr name="attr_color" format="color" />
            <attr name="attr_reference" format="reference" />
        </declare-styleable>
    </resources>
    

    activity_main.xml

        <com.sample.CustomView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:attr_bool="true"
            app:attr_color="@color/black"
            app:attr_dimension="9dp"
            app:attr_enum="type_2"
            app:attr_flag="left"
            app:attr_reference="@drawable/ic_launcher"
            app:attr_float="1.5"
            app:attr_fraction="50%"
            app:attr_int="1"
            app:attr_string="hello" />
    

    CustomView.kt

    val ta = context!!.obtainStyledAttributes(attrs, R.styleable.CustomView)
    
    val attrInt = ta.getInt(R.styleable.CustomView_attr_int, 0)
    Log.i("tianjf", "attr_int: $attrInt")
    
    val attrFloat = ta.getFloat(R.styleable.CustomView_attr_float, 0f)
    Log.i("tianjf", "attr_float: $attrFloat")
    
    val attrBool = ta.getBoolean(R.styleable.CustomView_attr_bool, false)
    Log.i("tianjf", "attr_bool: $attrBool")
    
    val attrString = ta.getString(R.styleable.CustomView_attr_string)
    Log.i("tianjf", "attr_string: $attrString")
    
    val attrEnum = ta.getInt(R.styleable.CustomView_attr_enum, 0)
    Log.i("tianjf", "attr_enum: $attrEnum")
    
    val attrFraction = ta.getFraction(R.styleable.CustomView_attr_fraction, 1, 1, 0f)
    Log.i("tianjf", "attr_fraction: $attrFraction")
    
    val attrFlag = ta.getInt(R.styleable.CustomView_attr_flag, 0)
    Log.i("tianjf", "attr_flag: $attrFlag")
    
    val attrDimension = ta.getDimension(R.styleable.CustomView_attr_dimension, 0f)
    val attrDimensionPixel = ta.getDimensionPixelSize(R.styleable.CustomView_attr_dimension, 0)
    Log.i("tianjf", "attr_dimension: $attrDimension")
    Log.i("tianjf", "attr_dimension: $attrDimensionPixel px")
    
    val attrColor = ta.getColor(R.styleable.CustomView_attr_color, 0)
    Log.i("tianjf", "attr_color: $attrColor")
    
    val attrReference = ta.getDrawable(R.styleable.CustomView_attr_reference)
    Log.i("tianjf", "attr_reference: $attrReference")
    

    打印如下:

     I/tianjf: attr_int: 1
     I/tianjf: attr_float: 1.5
     I/tianjf: attr_bool: true
     I/tianjf: attr_string: hello
     I/tianjf: attr_enum: 1
     I/tianjf: attr_fraction: 0.5
     I/tianjf: attr_flag: 2
     I/tianjf: attr_dimension: 13.5
     I/tianjf: attr_dimension: 14 px
     I/tianjf: attr_color: -16777216
     I/tianjf: attr_reference: android.graphics.drawable.BitmapDrawable@4fe5f57
    

    混合 format 类型

    format 还可以添加多个类型,比如系统的 android:background 就是混合类型:

    <attr name="background" format="reference|color" />
    

    相关文章

      网友评论

          本文标题:Andorid 自定义 View - 自定义属性基础

          本文链接:https://www.haomeiwen.com/subject/lnrrbrtx.html