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

当我们自定义 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. 添加如下内容

    
        
    

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 的就是声明。比如:。当属性已经在别的地方定义的时候,不能重复定义,否则会报错。
  1. 在 xml 中使用属性

  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 下声明。


    
        
        
    

声明完了就可以在 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



    
        
        
        
        
        
            
            
        
        
        
            
            
            
            
        
        
        
        
    

activity_main.xml

    

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 就是混合类型:


你可能感兴趣的:(Andorid 自定义 View - 自定义属性基础)