view的绘制
文章方法使用案例,参考博客:https://blog.csdn.net/whuhan2013/article/details/51404737
测量好一个View之后,我们就可以简单的重写onDraw()方法,并在Canvas 对象上来绘制所需要的图形。
要想在Android 的界面中绘制相应的图像,就必须在 Canvas 上进行绘制,Canvas就像是一个画板,使用Paint就可以在上面作画了。通常需要通过继承View并重写他的onDraw() 方法来完成绘制。我们来学习一下Canvas的用法:
下面是Canvas类常用的方法:
drawRect(RectF rect, Paint paint)
绘制区域,参数一为RectF一个区域
drawPath(Path path, Paint paint)
绘制一个路径,参数一为Path路径对象
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。
drawLine(float startX, float startY, float stopX, float stopY, Paintpaint)
画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint 画刷对象。
drawPoint(float x, float y, Paint paint)
画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。
drawText(String text, float x, floaty, Paint paint)
渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。
drawOval(RectF oval, Paint paint)
画椭圆,参数一是扫描区域,参数二为paint对象;
drawCircle(float cx, float cy, float radius,Paint paint)
绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象;
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
画弧,参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始, 参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象;
canvas.save();canvas.restore();
是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。
当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响
Paint使用
Paint 就相当于画笔,定义我们画图的各种属性.先来看一下Paint的style,共有3种
Paint类常用方法:
setARGB(int a, int r, int g, int b)
设置 Paint对象颜色,参数一为alpha透明值
setAlpha(int a)
设置alpha不透明度,范围为0~255
setAntiAlias(boolean aa)
是否抗锯齿
setColor(int color)
设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义
setTextScaleX(float scaleX)
设置文本缩放倍数,1.0f为原始
setTextSize(float textSize) 设置字体大小
setUnderlineText(booleanunderlineText)
设置下划线
setStyle(Paint.Style style)
设置画笔样式
取值有以下三种:
Paint.Style.FILL:填充内部
Paint.Style.FILL_AND_STROKE :填充内部和描边
Paint.Style.STROKE :描边
setStrokeWidth(float width)
设置画笔宽度
void reset()
清空画笔复位。
setPathEffect(PathEffect effect);
* 设置绘制路径的效果,如点画线等
(1)、CornerPathEffect——圆形拐角效果
eng:paint.setPathEffect(new CornerPathEffect(100));利用半径R=50的圆来代替原来两条直线间的夹角
(2)、DashPathEffect——虚线效果
setShader(Shader shader);
设置图像效果,使用Shader可以绘制出各种渐变效果
使用案例:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 创建画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,
mPaint.setColor(Color.GREEN);// 设置绿色
mPaint.setTextSize(18);
canvas.drawText("画圆:", 10, 20, mPaint);// 画文本
canvas.drawCircle(60, 20, 10, mPaint);// 小圆
canvas.drawCircle(120, 20, 20, mPaint);// 大圆
canvas.drawLine(60, 60, 100, 60, mPaint);// 画线
mPaint.setStrokeWidth(5);
canvas.drawLine(150, 50, 190, 70, mPaint);// 斜线
//画笑脸弧线
mPaint.setStyle(Paint.Style.STROKE);//设置空心
RectF oval1=new RectF(230,50,290,80);
canvas.drawArc(oval1, 180, 180, false, mPaint);//小弧形
oval1.set(310, 50, 370, 80);
canvas.drawArc(oval1, 180, 180, false, mPaint);//小弧形
oval1.set(260, 60, 340, 80);
canvas.drawArc(oval1, 0, 180, false, mPaint);//小弧形
mPaint.setColor(Color.YELLOW);
mPaint.setStrokeWidth(1.5f);
canvas.drawText("画扇形和椭圆:", 10, 120, mPaint);
mPaint.setStyle(Paint.Style.FILL);
/* 设置渐变色 这个正方形的颜色是改变的 */
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.LTGRAY }, null, Shader.TileMode.REPEAT); // 一个材质,打造出一个线性梯度沿著一条线。
mPaint.setShader(mShader);
RectF oval2 = new RectF(160, 100, 400, 240);// 设置个新的长方形,扫描测量
canvas.drawArc(oval2, 200, 130, true, mPaint);
// 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线
//画椭圆,把oval改一下
oval2.set(480,120,580,160);
canvas.drawOval(oval2, mPaint);
mPaint.reset();
mPaint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,
mPaint.setColor(Color.RED);// 设置绿色
mPaint.setTextSize(28);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawText("画三角形:", 10, 200, mPaint);
// 绘制这个三角形,你可以绘制任意多边形
Path path = new Path();
path.moveTo(180, 180);// 此点为多边形的起点
path.lineTo(250, 230);
path.lineTo(180, 230);
path.close(); // 使这些点构成封闭的多边形
canvas.drawPath(path, mPaint);
//定义一个矩形区域
RectF oval = new RectF(300,180,400,230);
//矩形区域内切椭圆
canvas.drawOval(oval, mPaint);
RectF rect = new RectF(420, 180, 500, 230);
canvas.drawRect(rect, mPaint);
RectF rect1 = new RectF(550, 180, 680, 230);
canvas.drawRoundRect(rect1,
30, //x轴的半径
30, //y轴的半径
mPaint);
//画贝塞尔曲线
canvas.drawText("画贝塞尔曲线:", 10, 260, mPaint);
mPaint.setColor(Color.BLUE);
Path path2=new Path();
path2.moveTo(200, 250);//设置Path的起点
path2.quadTo(250, 260, 280, 380); //设置贝塞尔曲线的控制点坐标和终点坐标
canvas.drawPath(path2, mPaint);//画出贝塞尔曲线
//画点
mPaint.setStyle(Paint.Style.FILL);
canvas.drawText("画点:", 10, 390, mPaint);
canvas.drawPoint(160, 390, mPaint);//画一个点
mPaint.setColor(Color.RED);
canvas.drawPoints(new float[]{160,400,165,400,170,400,175,400,180,400,185,400}, mPaint);//画多个点
//画图片,就是贴图
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
canvas.drawBitmap(bitmap, 260,360, mPaint);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
canvas.translate(canvas.getWidth()/2+200, 200); //将位置移动画纸的坐标点:
canvas.drawCircle(0, 0, 100, paint); //画圆圈
//使用path绘制路径文字
canvas.save();
canvas.translate(-75, -75);
Path path1 = new Path();
path1.addArc(new RectF(0,0,150,150), 180, 180);
Paint citePaint = new Paint(paint);
citePaint.setTextSize(14);
citePaint.setStrokeWidth(1);
canvas.drawTextOnPath("http://www.android777.com", path1, 28, 0, citePaint);
canvas.restore();
Paint tmpPaint = new Paint(paint); //小刻度画笔对象
tmpPaint.setStrokeWidth(1);
float y=100;
int count = 60; //总刻度数
for(int i=0 ; i <count ; i++){
if(i%5 == 0){
canvas.drawLine(0f, y, 0, y+12f, paint);
canvas.drawText(String.valueOf(i/5+1), -4f, y+25f, tmpPaint);
}else{
canvas.drawLine(0f, y, 0f, y +5f, tmpPaint);
}
canvas.rotate(360/count,0f,0f); //旋转画纸
}
//绘制指针
tmpPaint.setColor(Color.GRAY);
tmpPaint.setStrokeWidth(4);
canvas.drawCircle(0, 0, 7, tmpPaint);
tmpPaint.setStyle(Paint.Style.FILL);
tmpPaint.setColor(Color.YELLOW);
canvas.drawCircle(0, 0, 5, tmpPaint);
canvas.drawLine(0, 15, 0, -65, paint);
canvas.rotate(360/12,0f,0f);
paint.setStrokeWidth(1.5f);
canvas.drawLine(0, 10, 0, -55, paint);
}
效果如下: