1.自定义View的属性
首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。我们定义了字体,字体颜色,字体大小3
个属性,format是值该属性的取值类型:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="titleText" format="string" />
<attr name="titleTextColor" format="color" />
<attr name="titleTextSize" format="dimension" />
<declare-styleable name="CustomTitleView">
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources>
2.首先在布局中申明一个自定义View
<com.example.myapplication.CircleImage
android:id="@+id/pytcricle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
3.创建CircleImage类继承View
4.重写两个构造方法
public CircleImage(Context context) {
super(context);
}
public CircleImage(Context context, AttributeSet attrs) {
super(context, attrs);
}
5.重写onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMySize(100, widthMeasureSpec);
int height = getMySize(100, heightMeasureSpec);
if (width < height) {
height = width;
} else {
width = height;
}
setMeasuredDimension(width, height);
}
在onMeasure中对View尺寸进行规划,边界参数——widthMeasureSpec和heightMeasureSpec ,效率的原因以整数的方式传入。在
它们使用之前,首先要做的是使用
MeasureSpec类的静态方法getMode和getSize来译解
,如下面的片段所示:
private int getMySize(int defaultSize, int measureSpec) {
int mySize = defaultSize;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
switch (mode) {
case MeasureSpec.UNSPECIFIED: {//如果没有指定大小,就设置为默认大小
mySize = defaultSize;
//Log.e("main","un"+size);
break;
}
case MeasureSpec.AT_MOST: {//如果测量模式是最大取值为size
//我们将大小取最大值,你也可以取其他值
// Log.e("main","at"+size);
mySize = 100;
break;
}
case MeasureSpec.EXACTLY: {//如果是固定的大小,那就不要去改变它
// Log.e("main","ex"+size);
mySize = size;
break;
}
}
return mySize;
}
依据specMode的值,(
MeasureSpec有3种模式分别是UNSPECIFIED, EXACTLY和AT_MOST
)
.如果是AT_MOST,specSize 代表的是最大可获得的空间;
.如果是EXACTLY,specSize 代表的是精确的尺寸;
.如果是UNSPECIFIED,对于控件尺寸来说,没有任何参考意义。
.如果是EXACTLY,specSize 代表的是精确的尺寸;
.如果是UNSPECIFIED,对于控件尺寸来说,没有任何参考意义。
6.重写onDraw()方法
@Override
protected void onDraw(Canvas canvas) {
//调用父View的onDraw函数,因为View这个类帮我们实现了一些
// 基本的而绘制功能,比如绘制背景颜色、背景图片等
super.onDraw(canvas);
int r = getMeasuredWidth() / 2;//也可以是getMeasuredHeight()/2,本例中我们已经将宽高设置相等了
//圆心的横坐标为当前的View的左边起始位置+半径
int centerX = getLeft() + r;
//圆心的纵坐标为当前的View的顶部起始位置+半径
int centerY = getTop() + r;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
//开始绘制
canvas.drawCircle(centerX, centerY, r, paint);
}
最终结果