在Android开发中,我们经常会自定义View以满足特定需求。为了更好的控制View的样式,我们需要自定义View的属性。Android提供了一个很好的方法,即declare-styleable。
declare-styleable 是一个在XML中定义自定义view属性数组的方法。通过这种方式可以让我们方便的对自定义View进行属性的设置,从而实现更多样的效果和功能。
## 了解declare-styleable
在讲解如何使用declare-styleable之前,首先需要了解declare-styleable的基本概念。
declare-styleable是一个定义属性集合的数组,它可以用来指定一个View所包含的属性。因此,使用declare-styleable可以将一组属性集合到一个单独的命名空间中。
与其他资源类型类似,declare-styleable也是一个XML资源,可以在res/values/中定义它。定义声明样式的文件名通常为attrs.xml。
...
上面的代码中,我们定义了一个名为“自定义View名称”的declare-styleable资源包含3个属性:属性名称1、属性名称2和属性名称3。
下面,我们将详细讲解如何使用declare-styleable来自定义View属性。
## 使用declare-styleable自定义View属性
使用declare-styleable自定义View属性有三个主要的步骤:
1. 在XML中定义declare-styleable。
2. 在View的构造函数中读取属性。
3. 处理属性。
接下来,我们将详细讲解以上步骤。
### 步骤1:在XML中定义declare-styleable
定义declare-styleable是自定义View属性的基础,而XML就是我们定义declare-styleable的地方。
我们通常会在res/values/attrs.xml文件中定义declare-styleable。
例如,在res/values/attrs.xml文件中,我们定义了一个名为CustomTextView的自定义视图,并添加了一个名为foregroundColor的属性。
在上述代码中,我们声明了一个名为CustomTextView的declare-styleable,并且在其中添加了名为foregroundColor的属性。format属性定义了属性类型,此处我们定义了它可以参考其他的颜色资源或者直接指定为颜色值。
### 步骤2:在View的构造函数中读取属性
定义declare-styleable的工作完成之后,接下来就是在构造函数中实现读取属性的代码,为我们自定义的View添加上定义的属性。
我们可以通过context.obtainStyledAttributes()方法在自定义View的构造函数中获取到由这个View在attrs.xml中定义的属性。该方法接受一个属性数组作为其参数,属性数组就是在声明样式中描述的属性。该方法返回到一个TypedArray,通过该对象访问或更改属性。最后,我们调用该方法的recycle()方法将其回收。
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
int textColor = a.getColor(R.styleable.CustomTextView_foregroundColor, Color.BLACK);
a.recycle();
setTextColor(textColor);
}
在上面的代码中,我们定义了一个CustomTextView构造函数,使用context.obtainStyledAttributes()方法获取属性,并获取了一个TypedArray对象a。我们使用a.getColor()方法获取由属性名 R.styleable.CustomTextView_foregroundColor标识的属性值。根据我们在attrs.xml中声明的格式,这是一种颜色格式。与这样的数据类型有关,a.getColor方法的第二个参数在相应的属性没有指定值时就是 Color.BLACK。
最后,我们使用recycle()回收TypedArray对象a。
通过以上代码,我们成功地将foregroundColor属性添加到了自定义View中。现在我们只需要实现该属性即可。
### 步骤3:处理属性
我们已经在XML中定义了declare-styleable资源,并已在构造函数中读取了它们。现在,我们需要根据所读取的属性操作View。
表示自定义View的布局可能是非常简单或非常复杂的。对于CustomTextView,我们只是改变text的颜色。
public class CustomTextView extends androidx.appcompat.widget.AppCompatTextView {
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
int textColor = a.getColor(R.styleable.CustomTextView_foregroundColor, Color.BLACK);
a.recycle();
setTextColor(textColor);
}
}
在上述代码中,我们重写了setTextColor()方法,将属性值设为text颜色。
值得注意的是,我们可以使用不同的名称来识别属性,但在未将其添加到属性列表中之前,未定义属性不会起作用。如在自定义View中读取属性时不使用完全限定的属性名称,声明样式中定义的名称必须与使用的名称相同。
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CustomTextView, 0, 0);
int textColor = a.getColor(R.styleable.CustomTextView_foregroundColor, Color.BLACK);
a.recycle();
setTextColor(textColor);
}
在上面的代码中,我们对方法中的第三个和第四个参数使用了0,但这个行为是向后兼容的,并可以使用任何整数值。此处的值不是资源ID;它们只是用于查找特定样式的标识符。
## 总结
以上是使用declare-styleable自定义View属性的基本方法。通过这种方式,可以更好地控制自定义View的样式和功能。
在实现自定义View自己的属性时,请务必遵循Android的命名约定,并确保在自定义View的构造函数中取消使用的属性资源。
最后,需要注意的是,在自定义View实现时,我们还需要遵循以下要求:
- 只使用系统定义的格式,以及通过 format属性声明它。
- 定义和使用与Android内部样式相似的属性。
- 为 View基类维护一组预定义的格式声明。
- 您已在所有公开可用的XML资源中指定颜色。
- 如果必须添加其属性,则避免在子类中添加可能不必要的属性,而是使用属性的子集。