官方文档:https://developer.android.com/training/custom-views/create-view#java
示例:
1、为了自定义属性,在项目中添加
这段code定义了两个属性showText和lablePosition,属于PieChart实体。
代码的含义:
declare-styleable:一个属性组,其name必须和自定义View的名字相同。
attr:代表一个单独的属性,format代表属性的格式。
labelPosition属性中定义了默认值enum
定义的属性和系统的其他内置属性一样在xml中使用。唯一的区别是它们所属的命名空间(namespace)不同。
内置属性所属的命名空间:http://schemas.android.com/apk/res/android
自定义属性所属命名空间:http://schemas.android.com/apk/res/[your package name]
例如,如下是如何为PieChart使用这些自定义的属性:
xmlns:custom是加入命名空间,这个名称可以任意更改。如果修改为xmlns:xx,则使用属性时就是xx:showText = "true"。
注意此处的XML tag添加自定义view是完全限定名称。如果视图类是一个内部类,必须使用视图外部类的名称进一步限定它。
比如,PieChart有一个内部类叫做PieView,要使用此类中的自定义属性,可使用tag com.example.customviews.charting.PieChart$PieView.
自定义属性的取值都是取决于自定义View的布局文件中的对应的属性的值。如showText属性就为true,labelPosition属性就为left。
从XML布局创建视图时,XML tag中的所有属性都从资源包中读取,并作为AttributeSet传递到视图的构造函数中。虽然可以直接从AttributeSet中直接获取,但是这样做有一些缺点:
相反,将AttributeSet传递给obtainStyleAttributes()。这个方法回传一个已经解析过的资源引用和应用了样式的TypedArray数组。
PieChart如何读取它的属性:
public PieChart(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.PieChart,
0, 0);
try {
mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
} finally {
a.recycle();
}
}
注意,TypedArray对象是共享资源,必须使用后进行回收。
属性是控制视图行为和显示的有效方法,但是只能在视图初始化后时读取它们。要提供动态行为,需要为每个自定义属性创建gettter和setter方法。如下代码,展示了PieChart如何公开属性showText:
public boolean isShowText() {
return mShowText;
}
public void setShowText(boolean showText) {
mShowText = showText;
invalidate();
requestLayout();
}
setShowText函数里调用了invalidate()和requestLayout()函数,这两个函数对于视图能正常地显示有至关重要的作用。如果改变了可能影响显示的属性,必须废止(invalidate)当前视图,这样系统才会知道需要重绘。同样,如果一个可能影响视图size或shape的属性改变了,需要申请新的布局。如果没有调用这个两个方法,可能会出现难以发现的Bug。
自定义视图应该要定义事件监听器来通知重要事件。例如,PieChart有一个自定义方法OnCurrentItemChanged来通知listener,用户旋转了这个Pie chart以关注新的Chart Slice。