[置顶] 超详细!!canvas常用方法大全

时间:2021-02-19 19:10:09

要想绘制一些特别的效果的话,离不开Paint和Canvas  

Paint 就是画笔   Canvas 就是画布

本篇文章 主要讲的是Canvas    Canvas主要是在onDraw里面使用

首先我们先初始化一下Paints

public class MyView2 extends View {

private Paint mPaint;

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

public MyView2(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
}

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

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

mPaint.setColor(Color.rgb(0x91, 0xbe, 0xf0));
mPaint.setStrokeWidth(10);
mPaint.setStyle(Paint.Style.STROKE);

简单做了些操作    Paint具体的下一篇总结     简单初始化

画笔颜色---蕾姆蓝    画笔宽度5    画笔样式----描边


好了,下面开始画吧!

绘制点     

前两个参数代表 XY坐标  下一个参数是画笔
多画几个  怕看不清
//绘制一个点    第一个参数代表点的X  第二个Y
canvas.drawPoint(100, 200, mPaint);
canvas.drawPoint(300, 400, mPaint);
canvas.drawPoint(500, 600, mPaint);

运行效果如下 :
[置顶]        超详细!!canvas常用方法大全          

还有其他  画点的方法(传参不同)
第一个参数是传入浮点型的数组 每两个代表一个点     效果不用贴出来也能想出来了
 float[] points = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
// 绘制多个点 第一个参数 点的集合(两个数一个点)
canvas.drawPoints(points, mPaint);

下面这种是有选择的绘制多个点   --------  这个一点要切记两个数字为一个点
第二个参数代表的是从第几个数开始    第三个参数是选取几个数
float[] points = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
canvas.drawPoints(points, 2, 6, mPaint);
上面代码实际内容是  要(300,400)(500,600)(700,800) 这三个点
运行效果如下:

[置顶]        超详细!!canvas常用方法大全

(其他绘制也会有类似的重载方法  到时不赘述)

绘制线

两点连成一线  所以前四个参数分别是第一个点的XY和第二个点的XY坐标  
 //两点成一线  前两个参数是第一个点的XY坐标
canvas.drawLine(100,200,300,400,mPaint);
该方法也可以传入浮点型数组  和绘制点一致  不赘述(起始就是懒  哈哈哈)
效果如下图: [置顶]        超详细!!canvas常用方法大全


绘制矩形

前四个参数分别是矩形的左上角和右下角两个点的XY坐标(个人理解,并且觉得这么理解比较看懂~~)
所以------矩形的宽度  300-100 = 200   矩形的高度  400-200 = 200 是一个正方形
canvas.drawRect(100, 200, 300, 400, mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全
还有一种绘制矩形的方法:
通过新建一个区域范围 传入这个范围来绘制矩形  效果一样
Rect rect = new Rect(100,200,300,400);
canvas.drawRect(rect,mPaint);

绘制圆角矩形

前面一个参数是传入范围  Rect与RectF区别好像是RectF更加精确?具体不清楚第二第三个参数是代表圆角的弧度  数值越大 越园
 RectF rectF = new RectF(100,200,300,400);
canvas.drawRoundRect(rectF,50,50,mPaint);
运行效果如下:
[置顶]        超详细!!canvas常用方法大全

绘制圆

初中(或者小学)我们就知道画一个圆要有圆心和半径所以-----  前两个参数是 圆心坐标  第三个参数半径下面代码表示  圆心为(300,300)  半径为200 的正圆
        canvas.drawCircle(300,300,200,mPaint);

运行效果如下:[置顶]        超详细!!canvas常用方法大全

绘制椭圆

初中或者小学我们就知道圆是根据矩形的内切圆决定的正方形内切圆就是正圆   长方形的内切圆就是椭圆为了方便起见  我们同时画一个矩形和椭圆
canvas.drawRect(100, 200, 500, 400, mPaint);
canvas.drawOval(new RectF(100,200,500,400), mPaint);
运行效果如下:
[置顶]        超详细!!canvas常用方法大全

绘制圆弧

圆弧实际上就是圆或者椭圆的一部分为了方便直接画椭圆的圆弧吧为了直观   矩形 椭圆  然后换一下画笔颜色画弧
第一个参数是椭圆的范围   第二第三个参数是圆弧的起始角度和最终角度起始角度:0   就是X轴正方向的就是0角度 : 是顺时针  所以运行出来的圆弧是右下角(第四象限的圆弧)下一个参数是boolean类型  true就代表圆弧起点终点和圆心相连false就是不相连
canvas.drawRect(100, 200, 500, 400, mPaint);
canvas.drawOval(new RectF(100, 200, 500, 400), mPaint);
mPaint.setColor(Color.RED);
//前四个参数是矩形的范围
//然后两个 是起始角度和最后角度 起始是X轴正方向 旋转角度是顺时针
//下一个参数是 圆弧起点和终点是否和中心相连
canvas.drawArc(new RectF(100, 200, 500, 400), 0, 90, true, mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全


绘制多边形(Path)

三角形:
Path moveTo 是起点坐标lineTo方法是画线close是最后和起点连接所以画三角形  ----  确定起点 ----  画两条边  ------ close
Path path = new Path();
path.moveTo(100,100);
path.lineTo(100,500);
path.lineTo(700,500);
path.close();
canvas.drawPath(path , mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全


其实Path 里面还有很多方法的  
都很好理解  举个例子  .addCircle()方法   就是在路径上添加圆形下面代码就是在三角形上加上多个圆形
前三个参数不多说  圆心坐标和半径最后一个参数下面说(下面说的话更容易理解)
Path path = new Path();
path.moveTo(100,100);
path.lineTo(100,500);
path.lineTo(700,500);
path.close();
// canvas.drawPath(path , mPaint);
path.addCircle(100,100,30,Path.Direction.CW);
path.addCircle(100,200,30,Path.Direction.CW);
path.addCircle(100,300,30,Path.Direction.CW);
path.addCircle(100,400,30,Path.Direction.CW);
path.addCircle(100,500,30,Path.Direction.CW);
canvas.drawPath(path , mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全


在Path上绘制文字  
先分别画四个圆   然后在上面绘制文字drawTextOnPath() 方法 顾名思义  在Path上绘制文字前两个参数分别是 绘制的文字 和 path  第三个参数    与路径起始点的水平偏移距离第四个参数    与路径中心的垂直偏移量第一次看是不是一脸懵逼  哈哈哈 
第三个参数其实就是距离起始点的距离   圆形的话起始点也是终点 , 如果与起始点距离过大 则后面内容会压缩第四个是距离Path的 垂直距离   圆形的话就是距离园的那个线的距离   可以使负值
上面说了这里讲 Path.Direction.CW  和  CCW其实CW就是顺时针   CWW是逆时针   仔细看下面的图片就会发现  我设置CCW下面文字“测设文本1 测试文本2.....”是按逆时针分布的
String text = "测试文本1,测试文本2,测试文本3,测试文本";
Path path = new Path();
Path path1 = new Path();
Path path2 = new Path();
Path path3 = new Path();

path.addCircle(200, 200, 150, Path.Direction.CCW);
path1.addCircle(550, 200, 150, Path.Direction.CCW);
path2.addCircle(200, 700, 150, Path.Direction.CCW);
path3.addCircle(550, 700, 150, Path.Direction.CCW);

canvas.drawPath(path, mPaint);
canvas.drawPath(path1, mPaint);
canvas.drawPath(path2, mPaint);
canvas.drawPath(path3, mPaint);

//设置字体
mPaint.setTextSize(50);
canvas.drawTextOnPath(text, path, 0, 0, mPaint);
//第三个参数是与路径起始点的水平偏移距离
//起始点是X轴正方向,逆时针
//起始点也是终点 如果该数值过大则在终点压缩
canvas.drawTextOnPath(text, path1, 100, 0, mPaint);
//第四个参数是垂直偏移量
//就是距离圆心距离 可以为负数
canvas.drawTextOnPath(text, path2, 0, 100, mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全

绘制文字

上面要是仔细看了  其实绘制文字简单的很
第一个参数是文本   然后是范围  最后是画笔
 mPaint.setTextSize(50);
canvas.drawText("测试本本", 150, 150, mPaint);

运行效果如下:
[置顶]        超详细!!canvas常用方法大全

Path更多用法

path不只可以用来画多边形
下面直接贴这个代码
public class MyView4 extends View {

private Paint mPaint ;
private Path path ;


public MyView4(Context context) {
super(context, null);
}

public MyView4(Context context, @Nullable AttributeSet attrs) {
super(context, attrs, 0);
mPaint = new Paint();
path = new Path();
}

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

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mPaint.setTextSize(60);
mPaint.setStyle(Paint.Style.STROKE);

canvas.drawPath(path, mPaint);


}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(event.getX(), event.getY());
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}


里面代码很简单  随便看都知道在做什么
xml代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.administrator.test.MainActivity">

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@mipmap/mmm"
/>


<com.example.administrator.test.MyView4
android:layout_width="match_parent"
android:layout_height="match_parent"/>


</RelativeLayout>



运行效果如下[置顶]        超详细!!canvas常用方法大全

知道图片里面是谁的  加发私信给我  咱们互相交流一下   嘿嘿嘿~~~~~~~~
------------------------------------分割线--------------------------------------------------------------

注意


具体实行的时候  有时画 圆角矩形 或者画 椭圆的时候直接输入float类型的那个会报错
传入RectF  的对象就不会报错了  具体原因不清楚  ,  当初这里郁闷很久   这里写一下  防止和我一样的新手  遇到相同的的问题