关闭

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

标签: view
565人阅读 评论(0) 收藏 举报
分类:

要想绘制一些特别的效果的话,离不开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);

运行效果如下 :
          

还有其他  画点的方法(传参不同)

第一个参数是传入浮点型的数组 每两个代表一个点     效果不用贴出来也能想出来了

 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) 这三个点
运行效果如下:


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

绘制线

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



绘制矩形

前四个参数分别是矩形的左上角和右下角两个点的XY坐标(个人理解,并且觉得这么理解比较看懂~~)

所以------矩形的宽度  300-100 = 200   矩形的高度  400-200 = 200
是一个正方形

canvas.drawRect(100, 200, 300, 400, mPaint);

运行效果如下:

还有一种绘制矩形的方法:

通过新建一个区域范围 传入这个范围来绘制矩形  效果一样

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);
运行效果如下:


绘制圆

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

运行效果如下:

绘制椭圆

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

绘制圆弧

圆弧实际上就是圆或者椭圆的一部分
为了方便直接画椭圆的圆弧吧
为了直观   矩形 椭圆  然后换一下画笔颜色画弧

第一个参数是椭圆的范围   第二第三个参数是圆弧的起始角度和最终角度
起始角度: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);

运行效果如下:



绘制多边形(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);

运行效果如下:



其实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);

运行效果如下:



在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);

运行效果如下:


绘制文字

上面要是仔细看了  其实绘制文字简单的很

第一个参数是文本   然后是范围  最后是画笔

 mPaint.setTextSize(50);
        canvas.drawText("测试本本", 150, 150, mPaint);

运行效果如下:


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>



运行效果如下


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

------------------------------------分割线--------------------------------------------------------------

注意


具体实行的时候  有时画 圆角矩形 或者画 椭圆的时候直接输入float类型的那个会报错

传入RectF  的对象就不会报错了 
 
具体原因不清楚  ,  当初这里郁闷很久   这里写一下  防止和我一样的新手  遇到相同的的问题










1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16861次
    • 积分:653
    • 等级:
    • 排名:千里之外
    • 原创:46篇
    • 转载:1篇
    • 译文:0篇
    • 评论:15条
    最新评论