Android Canva和Paint学习

1,138 阅读9分钟
  • 先上图看效果

    在这里插入图片描述
    在这里插入图片描述

  • 圆角矩形的实现方法 在自定义View初始化的地方创建画笔,并设置相关属性

     //创建画笔,设置flag
     //ANTI_ALIAS_FLAG 抗锯齿
     //DITHER_FLAG 在绘制的时候启用抖动标志
     paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
     //给画笔设置颜色
     paint.setColor(0x9f345f56);
     //设置画笔线条宽度
     paint.setStrokeWidth(10);
     //将画笔设置为填充且描边
     paint.setStyle(Paint.Style.STROKE);
    
     //创建文字画笔
     mTextPaint = new Paint();
     //设置画笔颜色
     mTextPaint.setColor(0xff000000);
     //设置文字大小
     mTextPaint.setTextSize(36);
    

    在自定义View的onDraw()方法里面,调用canvas的drawRoundRect方法绘制圆角矩形。

     //绘制文字
     canvas.drawText("圆角矩形",50,70,mTextPaint);
     //定义一个矩形
     RectF rectF = new RectF(10,100,500,250);
     //绘制圆角矩形
     canvas.drawRoundRect(rectF,16,16,paint);
    
  • 圆形的实现方法 绘制圆形就是在自定义view的onDraw()方法里调用canvas的drawCircle()方法 绘制圆形是使用的画笔要设置属性填充

     //画笔设置属性填充且描边
     mCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
    
     //绘制文字
     canvas.drawText("圆形",170,320,mTextPaint);
     //绘制圆形
     canvas.drawCircle(200,500,150,mCirclePaint);
    
  • 圆环的实现方法

     //画笔只设置描边
     mRingPaint.setStyle(Paint.Style.STROKE);
     
     //绘制圆环
     canvas.drawCircle(200,910,150,mRingPaint);
    
  • 带有圆形线帽的线的实现方法

     canvas.drawText("带有圆形线帽的线",80,1190,mTextPaint);
     
     //设置画笔属性,绘制带有圆形线帽的线
     paint.setStrokeCap(Paint.Cap.ROUND);
     paint.setStrokeWidth(50);
     //绘制圆形线帽
     canvas.drawLine(70,1250,350,1250,paint);
    
  • 连接处为圆角的线的实现方法

     //绘制文字
     canvas.drawText("绘制线的连接处为圆角的线",60,1350,mTextPaint);
     
     //设置画笔属性,使画笔绘制path的时候连接处为圆角
     mRoundJoinPaint.setStrokeJoin(Paint.Join.ROUND);
     //新建path对象
     Path path = new Path();
     //path线绘制的起点移动到(70,1400)这个点处
     path.moveTo(70,1400);
     //从(70,1400)连接到(350,1400),是一条水平线
     path.lineTo(350,1400);
     //再从(350,1400)连接到(70,1600),是一条斜线
     path.lineTo(70,1600);
     //绘制这两条线,连接处为圆角
     canvas.drawPath(path,mRoundJoinPaint);
    
  • 连接处为平角的线的实现方法

     //绘制文字
     canvas.drawText("绘制线的连接处为平角的线",560,50,mTextPaint);
    
     //设置画笔属性,使画笔绘制path的时候连接处为平角
     mBevelJoinPaint.setStrokeJoin(Paint.Join.BEVEL);
     //创建path对象
     Path bevelPath = new Path();
     //移动绘制的起点为(600,100)
     bevelPath.moveTo(600,100);
     //从(600,100)连接到(850,100),是一条水平线
     bevelPath.lineTo(850,100);
     //再从(850,100)连接到(600,300),是一条斜线
     bevelPath.lineTo(600,300);
     //绘制这两条线,连接处为平角
     canvas.drawPath(bevelPath,mBevelJoinPaint);
    
  • 连接处为直角的线的实现方法

     //绘制文字
     canvas.drawText("绘制线的连接处为直角的线",560,390,mTextPaint);
     
     //设置画笔属性,使画笔绘制path的时候连接处为直角
     mMiterJoinPaint.setStrokeJoin(Paint.Join.MITER);
     //创建path对象
     Path miterPath = new Path();
     //把path的绘制起点移动到(600,430)这个点
     miterPath.moveTo(600,430);
     //从(600,430)连接到(850,430),是一条水平线
     miterPath.lineTo(850,430);
     //再从(850,430)连接到(600,630),是一条斜线
     miterPath.lineTo(600,630);
     //绘制这两条线,连接处为直角
     canvas.drawPath(miterPath,mMiterJoinPaint);
    
  • 使用CornerPathEffect实现连接处为圆角的效果

     //绘制文字
     canvas.drawText("使用 CornerPathEffect",560,710,mTextPaint);
     //绘制文字
     canvas.drawText("可以实现线段连接处圆角效果",560,760,mTextPaint);
     //把画笔属性置为默认值()
     mMiterJoinPaint.reset();
     
     //设置画笔的PathEffect属性为new CornerPathEffect(10),可使这个画笔绘制path连接处为圆角
     mMiterJoinPaint.setPathEffect(new CornerPathEffect(10));
     //设置画笔为描边
     mMiterJoinPaint.setStyle(Paint.Style.STROKE);
     //设置画笔的颜色
     mMiterJoinPaint.setColor(0xfff04598);
     //设置画笔绘制线条的宽度
     mMiterJoinPaint.setStrokeWidth(30);
     //创建path对象
     Path pathEffect = new Path();
     //绘制path的起点移动到(600,800)
     pathEffect.moveTo(600,800);
     //从(600,800)连接到(850,800),是一条水平线
     pathEffect.lineTo(850,800);
     //从(850,800)连接到(600,1000),是一条斜线
     pathEffect.lineTo(600,1000);
     //绘制这两条线,连接处为圆角
     canvas.drawPath(pathEffect,mMiterJoinPaint);
    
  • 使用DashPathEffect实现虚线的效果

     //绘制文字
     canvas.drawText("使用 DashPathEffect",560,1110,mTextPaint);
     //绘制文字
     canvas.drawText("可以实现线段虚线效果",560,1150,mTextPaint);
     //把画笔置为默认值
     mMiterJoinPaint.reset();
     mMiterJoinPaint.setPathEffect(new DashPathEffect(new float[]{10,5},0));
     mMiterJoinPaint.setStyle(Paint.Style.STROKE);
     mMiterJoinPaint.setColor(0xfff04598);
     mMiterJoinPaint.setStrokeWidth(30);
     //绘制连接处为直角的线
     Path dashPathEffect = new Path();
     dashPathEffect.moveTo(600,1200);
     dashPathEffect.lineTo(960,1200);
     canvas.drawPath(dashPathEffect,mMiterJoinPaint);
    
  • 实现PathDashPathEffect实现特殊的虚线效果(圆)

     Path ovalPaht = new Path();
     ovalPaht.addOval(dotRectF,Path.Direction.CW);
     mMiterJoinPaint.setPathEffect(new PathDashPathEffect(ovalPaht,dotRectF.width() * 1.5f,0,PathDashPathEffect.Style.TRANSLATE));
     pathDashEffect.moveTo(600,1370);
     pathDashEffect.lineTo(960,1370);
     canvas.drawPath(pathDashEffect,mMiterJoinPaint);
    
  • 实现PathDashPathEffect实现特殊的虚线效果(方块)

      //绘制文字
      canvas.drawText("使用 PathDashPathEffect",560,1310,mTextPaint);
      //绘制文字
      canvas.drawText("可以实现线段特殊的虚线效果",560,1350,mTextPaint);
      RectF dotRectF = new RectF(0,0,50,50);
      //把画笔置为默认值
      mMiterJoinPaint.reset();
      Path rectPaht = new Path();
      rectPaht.addRect(dotRectF,Path.Direction.CW);
      mMiterJoinPaint.setPathEffect(new PathDashPathEffect(rectPaht,dotRectF.width() * 1.5f,0,PathDashPathEffect.Style.TRANSLATE));
      mMiterJoinPaint.setStyle(Paint.Style.STROKE);
      mMiterJoinPaint.setColor(0xfff04598);
      mMiterJoinPaint.setStrokeWidth(30);
      //绘制连接处为直角的线
      Path pathDashEffect = new Path();
      pathDashEffect.moveTo(600,1450);
      pathDashEffect.lineTo(960,1450);
      canvas.drawPath(pathDashEffect,mMiterJoinPaint);
    
  • 实现PathDashPathEffect实现特殊的虚线效果(子弹)

     //绘制文字
     canvas.drawText("绘制分割线--子弹型",50,50,mTextPaint);
     RectF dotRectF = new RectF(0,0,50,50);
     Path bulletPath = new Path();
     bulletPath.lineTo(dotRectF.centerX(),dotRectF.top);
     bulletPath.addArc(dotRectF,-90,180);
     bulletPath.lineTo(dotRectF.left,dotRectF.bottom);
     bulletPath.lineTo(dotRectF.left,dotRectF.top);
     //绘制连接处为直角的线
     Path pathDashEffect = new Path();
     pathDashEffect.moveTo(50,82);
     mPaint.setPathEffect(new PathDashPathEffect(bulletPath,dotRectF.width() * 1.5f,0,PathDashPathEffect.Style.ROTATE));
     pathDashEffect.lineTo(460,83);
     canvas.drawPath(pathDashEffect,mPaint);
    
  • 实现PathDashPathEffect实现特殊的虚线效果(五角星)

      /*
      * 绘制五角星的原理就是把一个圆等分出5分,分别找出这5个等分点,从第一个点连接第三个点
      * 再连接第五个点,再连接第二个点,再连接第四个点,再连接第一个点,就是一个五角星了。
      */
      RectF dotRectF = new RectF(0,0,50,50);
      //绘制文字
      canvas.drawText("绘制分割线--五角星",650,50,mTextPaint);
      Path ovalPath = new Path();
      //这个表示绘制椭圆,因为定义的dotRectF是一个正方形,所以最终绘制出来的是个圆
      ovalPath.addOval(dotRectF, Path.Direction.CW);
      /*
      * PathMeasure类似一个Path坐标计算器,使用它可以求出path上一些点的坐标
      * ovalPath 传入的待求的path
      * false表示这个path不要求闭合,true表示path是闭合的,即使path不是闭合的,它也会给补上最后一条线
      * 给闭合
      */
      PathMeasure pathMeasure = new PathMeasure(ovalPath,false);
      //这个这个圆(ovalPath)的长度
      float length = pathMeasure.getLength();
      //把这个圆平均分成五段,获取每段的长度
      float split = length/5;
      //表示把圆平均分成5段的上面的5个点的坐标
      //比如startPos[1]表示第一个点的横坐标,startPos[2]表示第一个点的纵坐标,startPos[3]表示第二个点的横坐标,startPos[4]表示第二个点的纵坐标,依次类推
      float[] starPos = new float[10];
      //表示每个点的横纵坐标
      float[] pos = new float[2];
      //表示这段圆弧切点的横纵坐标
      float[] tan = new float[2];
      //一个for循环,对每段圆弧进行处理
      for (int i = 0; i < 5; i++) {
      	//求每段圆弧的起点坐标和切点坐标分别存储在pos和tan中
          pathMeasure.getPosTan(split * i,pos,tan);
          //把每段圆弧起点的横纵坐标赋值给starPos
          starPos[i*2 + 0] = pos[0];
          starPos[i*2 + 1] = pos[1];
      }
      //定义五角星线
      Path starPath = new Path();
      //移动到圆的第一个点
      starPath.moveTo(starPos[0],starPos[1]);
      //圆的第一个点和第第三个点相连
      starPath.lineTo(starPos[4],starPos[5]);
      //再连圆的第五个点
      starPath.lineTo(starPos[8],starPos[9]);
      //再连圆的第二个点
      starPath.lineTo(starPos[2],starPos[3]);
      //再连第四个点
      starPath.lineTo(starPos[6],starPos[7]);
      //再连第一个点
      starPath.lineTo(starPos[0],starPos[1]);
      //定义一个矩阵
      Matrix matrix = new Matrix();
      //表示反向旋转90度操作
      matrix.postRotate(-90,dotRectF.centerX(),dotRectF.centerY());
      //执行对五角星反向旋转90度
      starPath.transform(matrix);
      //定义一条path
      Path starLinePath = new Path();
      starLinePath.moveTo(650,82);
      //设置画笔属性,使画笔画出来的虚线线是五角星,因为PathDashPathEffect添加了我们刚才定义的五角星
      mStarPaint.setPathEffect(new PathDashPathEffect(starPath,75,0,PathDashPathEffect.Style.TRANSLATE));
      starLinePath.lineTo(960,83);
      //绘制五角星虚线
      canvas.drawPath(starLinePath,mStarPaint);
    
  • 饼状图实现

     //画笔属性设置为默认值
     mPaint.reset();
     //设置画笔颜色
     mPaint.setColor(0xffff0000);
     //设置画笔为填充
     mPaint.setStyle(Paint.Style.FILL);
     //绘制文字
     canvas.drawText("绘制饼状图",50,250,mTextPaint);
     //定义一个矩形
     RectF rectF = new RectF(300,300,600,600);
     //绘制第一个扇形(圆弧)
     canvas.drawArc(rectF,0,40,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xff0a6586);
     //绘制第二个扇形
     //recfF表示扇形所在的区域,40是startAngle圆弧的起始角度,60是sweepAngle,表示圆弧扫过的角度
     canvas.drawArc(rectF,40,60,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xffa04586);
     //绘制第三个扇形
     canvas.drawArc(rectF,100,20,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xf06f0ac6);
     //绘制第四个扇形
     canvas.drawArc(rectF,120,30,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xff9a450f);
     //绘制第五个扇形
     canvas.drawArc(rectF,150,90,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xfa6759c6);
     //绘制第六个扇形
     canvas.drawArc(rectF,240,100,true,mPaint);
     //改变画笔颜色
     mPaint.setColor(0xff8b65a0);
     //绘制第七个扇形,整个饼状图就绘制完毕了
     canvas.drawArc(rectF,340,20,true,mPaint);
     //绘制饼状图的表示
     //定义一个矩形,四个参数分别表示left,top,right,bottom
     RectF colorRectF = new RectF(700,450,750,470);
     //给画笔设置颜色
     mPaint.setColor(0xffff0000);
     //绘制小矩形
     canvas.drawRect(colorRectF,mPaint);
     //绘制文字,770表示文字最左边的位置,475表示文字最底部位置
     canvas.drawText("棉花",770,475,mTextPaint);
     RectF colorRectF1 = new RectF(700,410,750,430);
     mPaint.setColor(0xff0a6586);
     canvas.drawRect(colorRectF1,mPaint);
     canvas.drawText("小麦",770,435,mTextPaint);
     RectF colorRectF2 = new RectF(700,490,750,510);
     mPaint.setColor(0xffa04586);
     canvas.drawRect(colorRectF2,mPaint);
     canvas.drawText("大豆",770,515,mTextPaint);
     RectF colorRectF3 = new RectF(700,530,750,550);
     mPaint.setColor(0xf06f0ac6);
     canvas.drawRect(colorRectF3,mPaint);
     canvas.drawText("花生",770,555,mTextPaint);
     RectF colorRectF4 = new RectF(700,570,750,590);
     mPaint.setColor(0xff9a450f);
     canvas.drawRect(colorRectF4,mPaint);
     canvas.drawText("甘蔗",770,595,mTextPaint);
     RectF colorRectF5 = new RectF(700,610,750,630);
     mPaint.setColor(0xfa6759c6);
     canvas.drawRect(colorRectF5,mPaint);
     canvas.drawText("油菜",770,635,mTextPaint);
     RectF colorRectF6 = new RectF(700,650,750,670);
     canvas.drawText("玉米",770,675,mTextPaint);
     mPaint.setColor(0xff8b65a0);
    canvas.drawRect(colorRectF6,mPaint);