在画图之前我们还需要了解一下自定义中的需要重写的方法和一些基本的API
Android中View的绘制是从根节点开始的,这是一个自上而下的过程,主要需要进过三个步骤:Measure(测量大小) –> Layout(摆放位置) –> Draw(绘制内容)。
自定义view的绘制流程
Paint类:
Paint翻译为“画笔”,为绘图定义各种参数:颜色、线条样式、图案样式等。
Paint类一些常用的属性和基本方法
canvas类:这个类相当于一个画布,你可以在里面画很多东西;
Canvas类的用法
package com.bawe.demo1130;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import static android.content.ContentValues.TAG;
/**
* Created by Administrator on 2017/11/30.
* Android自定义View
*/
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
//测量
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d(TAG, "onMeasure: ");
}
//绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d(TAG, "onDraw: ");
// 创建画笔
Paint p = new Paint();
p.setTextSize(50);// 设置字体大小
/**
* 画圆
*/
p.setColor(Color.RED);// 设置红色
canvas.drawText("画圆:", 50, 100, p);// 画文本
// 参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象
canvas.drawCircle(300, 70, 30, p);// 小圆
// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了
p.setAntiAlias(true);
canvas.drawCircle(400, 70, 50, p);// 大圆
/**
* 画线
* 参数一起始点的x轴位置,
* 参数二起始点的y轴位置,
* 参数三终点的x轴水平位置,
* 参数四y轴垂直位置,最后一个参数为Paint 画刷对象。
*/
p.setColor(Color.RED);
canvas.drawText("画线:", 50, 200, p);
p.setColor(Color.BLACK);// 设置颜色
canvas.drawLine(270, 170, 330, 170, p);// 画线
canvas.drawLine(400, 170, 450, 210, p);// 斜线
/**
* 画笑脸弧线
*/
p.setColor(Color.RED);
canvas.drawText("笑脸弧线:", 50, 300, p);
p.setColor(Color.BLACK);// 设置颜色
p.setStyle(Paint.Style.STROKE);//设置空心
RectF oval1 = new RectF(150, 20, 180, 40);
/**
* 画弧,
* 参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,
* 参数二是起始角(度)在电弧的开始,
* 参数三扫描角(度)开始顺时针测量的,
* 参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,
* 参数五是Paint对象;
*/
canvas.drawArc(oval1, 180, 180, false, p);//小弧形
oval1.set(190, 20, 220, 40);
canvas.drawArc(oval1, 180, 180, false, p);//小弧形
oval1.set(160, 30, 210, 60);
canvas.drawArc(oval1, 0, 180, false, p);//小弧形
/**
* 画矩形
*/
p.setColor(Color.RED);
canvas.drawText("画矩形:", 50, 400, p);
p.setColor(Color.GRAY);// 灰色
p.setStyle(Paint.Style.FILL);//设置填满
canvas.drawRect(300, 350, 320, 370, p);// 正方形
canvas.drawRect(300, 380, 350, 410, p);// 长方形
/**
* 画扇形和椭圆
*/
p.setColor(Color.RED);
canvas.drawText("画扇形和椭圆:", 50, 500, p);
/* 设置渐变色 这个正方形的颜色是改变的 */
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.LTGRAY}, null, Shader.TileMode.REPEAT); // 一个材质,打造出一个线性梯度沿着一条线。
p.setShader(mShader);
p.setColor(Color.BLUE);
RectF oval2 = new RectF(420, 470, 480, 530);// 设置个新的长方形,扫描测量
canvas.drawArc(oval2, 200, 130, true, p);
/**
* 画弧,第一个参数是RectF:
* 该类是第二个参数是角度的开始,
* 第三个参数是多少度,
* 第四个参数是真的时候画扇形,是假的时候画弧线
*/
// 画椭圆,把oval改一下
oval2.set(500, 470, 520, 500);
/**
* 画椭圆,参数一是扫描区域,参数二为paint对象;
*/
canvas.drawOval(oval2, p);
/**
* 画三角形
*/
p.setColor(Color.RED);
canvas.drawText("画三角形:", 50, 600, p);
// 绘制这个三角形,你可以绘制任意多边形
Path path = new Path();
path.moveTo(400, 550);// 此点为多边形的起点
path.lineTo(400, 600);
path.lineTo(500, 600);
path.close(); // 使这些点构成封闭的多边形
canvas.drawPath(path, p);
/**
* 任意多边形
*/
// 你可以绘制很多任意多边形,比如下面画六连形
p.reset();//重置
p.setColor(Color.LTGRAY);
p.setStyle(Paint.Style.STROKE);//设置空心
Path path1 = new Path();
path1.moveTo(180, 200);
path1.lineTo(200, 200);
path1.lineTo(210, 210);
path1.lineTo(200, 220);
path1.lineTo(180, 220);
path1.lineTo(170, 210);
path1.close();//封闭
canvas.drawPath(path1, p);
/**
* Path类封装复合(多轮廓几何图形的路径
* 由直线段、二次曲线,和三次方曲线,也可画以油画。
* drawPath(路径、油漆),要么已填充的或抚摸(基于油漆的风格),或者可以用于剪断或画画的文本在路径。
*/
/**
* 画圆角矩形
*/
p.setStyle(Paint.Style.FILL);//充满
p.setColor(Color.LTGRAY);
// 设置画笔的锯齿效果
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setTextSize(50);
canvas.drawText("画圆角矩形:", 50, 700, p);
p.setColor(Color.GRAY);
// 设置个新的长方形
RectF oval3 = new RectF(400, 650, 520, 700);
canvas.drawRoundRect(oval3, 20, 15, p);//第二个参数是x半径,第三个参数是y半径
/**
* 画贝塞尔曲线
*/
p.setColor(Color.RED);
canvas.drawText("画贝塞尔曲线:", 50, 800, p);
p.reset();
p.setStyle(Paint.Style.STROKE);
p.setColor(Color.BLUE);
Path path2 = new Path();
// 设置Path的起点
path2.moveTo(500, 850);
// 设置贝塞尔曲线的控制点坐标和终点坐标
path2.quadTo(400, 700, 410, 800);
/**
* 绘制一个路径,参数一为Path路径对象
*/
canvas.drawPath(path2, p);//画出贝塞尔曲线
/**
* 画点
*/
p.setTextSize(50);
p.setColor(Color.RED);
p.setStyle(Paint.Style.FILL);
canvas.drawText("画点:", 50, 900, p);
/**
* 画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。
*/
p.setColor(Color.RED);
canvas.drawPoint(400, 900, p);// 画一个点
canvas.drawPoints(new float[]{60, 400, 65, 400, 70, 400}, p);// 画多个点
/**
* 画图片,就是贴图
*/
canvas.drawText("画图片:", 50, 1000, p);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
/**
* 贴图,
* 参数一就是我们常规的Bitmap对象,
* 参数二是源区域(这里是bitmap),
* 参数三是目标区域(应该在canvas的位置和大小),
* 参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。
*/
canvas.drawBitmap(bitmap, 370, 950, p);
}
//位置
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
Log.d(TAG, "onLayout: ");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "onTouchEvent: ");
return super.onTouchEvent(event);
}
}