3.View自定义布局canvas画布知识

一、基础知识

1.Canvas画布

2.Paint画笔

3.Canvas的常用方法:drawArc(画圆弧)、drawCircle(画圆)、drawLine(画线)

二、常用方法的讲解

1.drawArc(RectF,starrtAngle,sweepAngle,useCenter,paint)

我们通常使用该方法画圆弧,第一参数RectF表示我们绘画的区域(范围),第二个参数是圆弧开始的度数(这里度数表示与上课讲的不一样,课堂讲的角度是从x轴逆时针方向开始,而这里是逆时针算,所以90度是6点钟),第三个参数是扫过的角度,第四参数是否居中,第五个参数是画笔。

2.drawCircle(cx,cy,radius,paint)

我们通常使用该方法画圆,第一、二表示圆心的坐标,坐标原点是手机屏幕的左上角,屏幕上的位置都是正数,与我们平时在课堂讲的不一样,第三个参数是半径,第四个参数是画笔

3.drawLine(startX,startY,stopX,stopY,paint)

我们通常使用该方法画线条,课堂上我们都学过两点确定一条直线,所以确定两个点就可以画一条直线了。第一、二个参数表示第一个点的参数,第三、四表示第二个点的参数。

4.DectF(left,top,right,bottom)

我们通常使用该方法定义一片区域,left表是与屏幕左边的距离,top表示与屏幕上边的距离,right表示与屏幕左边的距离,bottom表示与屏幕顶部距离,都是以顶部或左边为基准。

三、使用案例

画这样的一个图形有点复杂,但找对方法就很容易。

看到这样的一个图形,先分析(这个很重要),要怎么画这个图形,下面可以这样想:

1.最外面的线条,你可以看成是一个圆弧只不过这个圆弧比较窄(窄成线了)

2.而时刻就是线条drawLine就可以,只不过要用到旋转布局,这个后面会讲到。

3.里面的圆环也是一个扇形drawArc

4.指针是drawLine

5.里面的圆可以drawArc或drawCircle都可以,drawCircle比较方便

注:定义画笔的宽度pain.setStockWidth(表示画笔粗细,到时定义扇形的宽也是通过这个方法来设置的)

先把代码补上,来日再讲解

/**
* 时表
*/
public class PanelView extends View {
private int width;
private int height;
private int percent = 50;
private int scendArcWidth;//第二个弧的宽度
private int minCircleRadius;//最小圆的半径
private int rectWidth;//文字矩形的宽
private String text;//文字内容
private int textSize;//文字的大小
private int textColor;//文字颜色
private int arcColor = Color.WHITE;//
private int minCircleColor = Color.WHITE;//小圆和指针颜色
private int tikeCount = 13;//刻度的个数
private int tikeWidth = 3;//刻度的长度
private Context context;

public PanelView(Context context) {
super(context);
}

public PanelView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}

public PanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}

public PanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context,attrs);
}

private void init(Context context,AttributeSet attributeSet){
TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.PanelView);
arcColor = typedArray.getColor(R.styleable.PanelView_arcColor,
Color.parseColor("#5FB1ED"));
minCircleColor = typedArray.getColor(R.styleable.PanelView_minCircleColor,
Color.parseColor("#5FB1ED"));
tikeCount = typedArray.getInt(R.styleable.PanelView_tikeCount,0);
textSize = typedArray.getDimensionPixelSize(R.styleable.PanelView_textSize,0);
text = typedArray.getString(R.styleable.PanelView_android_text);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY){
width = widthSize;
}
if(heightMode == MeasureSpec.EXACTLY){
height = heightSize;
}
setMeasuredDimension(width,height);
}

@Override
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
int strokeWidth = 10;
p.setStrokeWidth(strokeWidth);
p.setAntiAlias(true);
p.setStyle(Paint.Style.STROKE);
p.setColor(arcColor);
//最外面线条
canvas.drawArc(new RectF(strokeWidth,strokeWidth,width - strokeWidth,height - strokeWidth),
145,250,false,p);
strokeWidth = 50;
p.setStrokeWidth(strokeWidth);
//里面的第二个圆弧
RectF secondRectF = new RectF(strokeWidth + 50,strokeWidth + 50,
width - strokeWidth - 50,height - strokeWidth - 50);
float percent = this.percent / 100f;

//充满的圆弧的度数 -5是大小弧的偏差
float fill = 250 * percent;

//空的圆弧的度数
float empty = 250 - fill;

if(percent == 0) {
p.setColor(Color.WHITE);
}

//弧1
canvas.drawArc(secondRectF,135,11,false,p);
//弧2
canvas.drawArc(secondRectF, 145, fill, false, p);
p.setColor(Color.WHITE);
//弧3
canvas.drawArc(secondRectF,145 + fill, empty,false,p);
if(percent == 1) p.setColor(arcColor);
//弧4
canvas.drawArc(secondRectF,144+fill+empty,10,false,p);

//绘制小圆外圆
p.setColor(arcColor);
p.setStrokeWidth(3);
canvas.drawCircle(width / 2, height / 2, 30,p);

//绘制内圆
p.setColor(minCircleColor);
p.setStrokeWidth(8);
minCircleRadius = 15;
canvas.drawCircle(width / 2,height / 2,minCircleRadius,p);

//绘制刻度旋转画布
p.setColor(arcColor);
//绘制第一条最上面的刻度
tikeWidth = 30;
p.setStrokeWidth(6);
canvas.drawLine(width/2,6,width/2,tikeWidth,p);
tikeCount = 13;
float angle = 250f/tikeCount;
//通过旋转画布 绘制右面的刻度
for(int i = 0;i < tikeCount/2;i++) {
canvas.rotate(angle,width/2,height/2);
canvas.drawLine(width/2,6,width/2,tikeWidth,p);
}
canvas.rotate(-angle * tikeCount/2,width / 2, height / 2);
for(int i = 0;i < tikeCount/2;i++){
canvas.rotate(-angle,width/2,height/2);
canvas.drawLine(width/2,6,width/2,tikeWidth,p);
}
canvas.rotate(angle * tikeCount/2,width / 2, height / 2);

//绘制指针
p.setColor(minCircleColor);
p.setStrokeWidth(4);

//按照百分比绘制刻度
canvas.rotate((250 * this.percent - 250/2),width / 2,height / 2);
canvas.drawLine(width / 2,
strokeWidth + 50 + strokeWidth/2,
width / 2, height / 2 - minCircleRadius, p);
//将画布旋转回来
canvas.rotate(-(250 * percent - 250/2),width/2,height/2);
super.onDraw(canvas);
}
}
原文地址:https://www.cnblogs.com/riyueqian/p/14698837.html