要想绘制一些特别的效果的话,离不开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};上面代码实际内容是 要(300,400)(500,600)(700,800) 这三个点 运行效果如下:
canvas.drawPoints(points, 2, 6, mPaint);
(其他绘制也会有类似的重载方法 到时不赘述)
绘制线
两点连成一线 所以前四个参数分别是第一个点的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 的对象就不会报错了 具体原因不清楚 , 当初这里郁闷很久 这里写一下 防止和我一样的新手 遇到相同的的问题