一、效果图
二、源代码
2.1 第一张效果图
package com.study.yang.drawgraphicaldemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* 绘制圆弧
*/
public class DrawSectorDemo extends View {
private Paint rectFPaint;
private Paint circlePaint;
public DrawSectorDemo(Context context) {
this(context, null);
}
public DrawSectorDemo(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawSectorDemo(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
circlePaint = new Paint();
circlePaint.setColor(Color.RED);
circlePaint.setAntiAlias(true);
//设置画笔为空
circlePaint.setStyle(Paint.Style.STROKE);
rectFPaint = new Paint();
rectFPaint.setColor(Color.BLUE);
rectFPaint.setAntiAlias(true);
//设置画笔为空
rectFPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF rectF = new RectF(0, 0, 800, 800);
canvas.drawRect(rectF, rectFPaint);
canvas.drawArc(rectF, -60, 60, false, circlePaint);
canvas.drawCircle(100, 100, 50, rectFPaint);
}
}
2.2 第二张效果图
package com.study.yang.drawgraphicaldemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* 绘制内凹图形
*/
public class InternalConcaveDemo extends View {
private Paint rectFPaint;
private Paint circlePaint;
private RectF rectF1;
private RectF rectF2;
private RectF rectF3;
private RectF rectF4;
public InternalConcaveDemo(Context context) {
this(context, null);
}
public InternalConcaveDemo(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InternalConcaveDemo(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
circlePaint = new Paint();
circlePaint.setColor(Color.RED);
circlePaint.setAntiAlias(true);
circlePaint.setStyle(Paint.Style.STROKE);
rectFPaint = new Paint();
rectFPaint.setColor(Color.BLUE);
rectFPaint.setAntiAlias(true);
rectFPaint.setStyle(Paint.Style.FILL);
rectF1 = new RectF(-50, 100, 50, 200);
rectF2 = new RectF(50, 0, 150, 100);
rectF3 = new RectF(350, 0, 450, 100);
rectF4 = new RectF(450, 100, 550, 200);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
userArcToApi(canvas);
drawRing(canvas);
drawFanLeaf(canvas);
drawMoon(canvas);
drawUnion(canvas);
// drawXor(canvas);
Path path = new Path();
path.moveTo(500, 500);
path.cubicTo(500, 500, 600, 700, 900, 800);
// path.lineTo(1100, 1100);
rectFPaint.setColor(Color.RED);
canvas.drawPath(path, rectFPaint);
}
/**
* 去除两者之间的图形
*
* @param canvas
*/
private void drawXor(Canvas canvas) {
Path path1 = new Path();
path1.addCircle(1200, 1200, 100, Path.Direction.CCW);
Path path2 = new Path();
path2.addCircle(1250, 1250, 100, Path.Direction.CCW);
path1.op(path2, Path.Op.XOR);//去除两者之间的图形
rectFPaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path1, rectFPaint);
}
/**
* 画联合
*
* @param canvas
*/
private void drawUnion(Canvas canvas) {
Path path1 = new Path();
path1.addCircle(900, 500, 100, Path.Direction.CCW);
Path path2 = new Path();
path2.addCircle(950, 550, 100, Path.Direction.CCW);
path1.op(path2, Path.Op.UNION);//联结两条路径
canvas.drawPath(path1, rectFPaint);
}
/**
* 画月亮
*
* @param canvas
*/
private void drawMoon(Canvas canvas) {
Path path1 = new Path();
path1.addCircle(900, 900, 100, Path.Direction.CCW);
Path path2 = new Path();
path2.addCircle(950, 950, 100, Path.Direction.CCW);
path1.op(path2, Path.Op.REVERSE_DIFFERENCE);//从第二条路径中减去第一条路径
canvas.drawPath(path1, rectFPaint);
}
/**
* 画扇叶
*
* @param canvas
*/
private void drawFanLeaf(Canvas canvas) {
Path path1 = new Path();
path1.addCircle(600, 600, 100, Path.Direction.CCW);
Path path2 = new Path();
path2.addCircle(650, 650, 100, Path.Direction.CCW);
path1.op(path2, Path.Op.INTERSECT);//两者相交的部分
canvas.drawPath(path1, rectFPaint);
}
/**
* 画圆环
*
* @param canvas
*/
private void drawRing(Canvas canvas) {
Path bigPath = new Path();
bigPath.addCircle(300, 300, 50, Path.Direction.CCW);
Path smallPath = new Path();
smallPath.addCircle(300, 300, 25, Path.Direction.CCW);
bigPath.op(smallPath, Path.Op.DIFFERENCE); //大减小
canvas.drawPath(bigPath, rectFPaint);
}
/**
* 用addArc这个API来绘制弧线,这个API更适合来绘制扇形
*
* @param canvas
*/
private void useAddArcApi(Canvas canvas) {
Path path = new Path();
path.addArc(rectF1, 90, -90);
path.lineTo(50, 50);
path.addArc(rectF2, 180, 90);
path.lineTo(400, 0);
path.addArc(rectF3, -90, 90);
path.lineTo(450, 250);
path.addArc(rectF4, 180, -90);
path.lineTo(0, 300);
canvas.drawPath(path, rectFPaint);
}
/**
* 用arcTo这个API来绘制弧线
*
* @param canvas
*/
private void userArcToApi(Canvas canvas) {
Path path = new Path();
//逆时针画弧线
path.arcTo(rectF1, 90, -90);
path.lineTo(50, 50);
//顺时针画弧线
path.arcTo(rectF2, 180, 90);
path.lineTo(400, 0);
//顺时针画弧线
path.arcTo(rectF3, -90, 90);
path.lineTo(450, 150);
//逆时针画曲线
path.arcTo(rectF4, 180, -90);
path.lineTo(0, 200);
canvas.drawPath(path, rectFPaint);
}
/**
* 绘制半角路径
*
* @param canvas
*/
private void drawPath(Canvas canvas) {
Path path = new Path();
path.moveTo(50, 0);
path.lineTo(50, 50);
path.lineTo(0, 50);
path.close();
// canvas.drawPath(path, rectFPaint);
Path path1 = new Path();
path1.addArc(rectF1, 0, 90);
// path.close();
//path减去path1
path.op(path1, Path.Op.DIFFERENCE);
canvas.drawPath(path, rectFPaint);
}
}
2.3 第三张效果图
package com.study.yang.drawgraphicaldemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
/**
* 太极View
*/
public class TaiChiView extends View {
/**
* 太极矩形外围
*/
private RectF taiChiRectF;
/**
* 白色路径
*/
private Path whitePath = new Path();
private Paint whitePaint = new Paint();
private Region whiteRegion = new Region();
/**
* 黑色路径
*/
private Path blackPath = new Path();
private Paint blackPaint = new Paint();
private Region blackRegion = new Region();
private float radius;
private final int BLACK_FLAG = 0;
private final int WRITE_FLAG = 1;
private int touchFlag = -1;
private TaiJiListener mListener;
public TaiChiView(Context context) {
this(context, null);
}
public TaiChiView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TaiChiView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
/**
* 初始化数据
*
* @param context
*/
private void init(Context context) {
//白色
whitePaint.setColor(Color.WHITE);
whitePaint.setAntiAlias(true);
//黑色
blackPaint.setColor(Color.BLACK);
blackPaint.setAntiAlias(true);
}
/**
* 当尺寸改变的时候绘制图形
*
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int side = w > h ? h : w;
Region totalRegion = new Region(0, 0, w, h);
taiChiRectF = new RectF(0, 0, side, side);
radius = side / 2;
RectF smallTopRectF = new RectF(radius / 2, 0, radius * 3 / 2, radius);
RectF smallBottomRectF = new RectF(radius / 2, radius, radius * 3 / 2, side);
//白色路径添加
whitePath.addArc(taiChiRectF, 90, 180);
whitePath.moveTo(radius, 0);
whitePath.addArc(smallTopRectF, 270, 180);
whitePath.moveTo(radius, radius);
//逆时针
whitePath.arcTo(smallBottomRectF, 270, -180);
/**
* 将区域设置为路径和所描述的区域的剪辑。
* 如果结果区域为非空,则返回true。这就产生了一个区域
* 这与路径绘制的像素相同(没有抗锯齿)。
*/
//将白色路径设置
whiteRegion.setPath(whitePath, totalRegion);
//黑色路径添加
blackPath.addArc(taiChiRectF, 270, 180);
blackPath.moveTo(radius, side);
blackPath.addArc(smallBottomRectF, 90, 180);
blackPath.moveTo(radius, radius);
//逆时针
blackPath.arcTo(smallTopRectF, 90, -180);
blackRegion.setPath(blackPath, totalRegion);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//白色
canvas.drawPath(whitePath, whitePaint);
canvas.drawCircle(radius, radius / 2, radius / 8, blackPaint);
//黑色
canvas.drawPath(blackPath, blackPaint);
canvas.drawCircle(radius, radius * 3 / 2, radius / 8, whitePaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
int currentFlag = -1;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
touchFlag = getTouchFlag(x, y);
currentFlag = touchFlag;
break;
case MotionEvent.ACTION_MOVE:
currentFlag = getTouchFlag(x, y);
break;
case MotionEvent.ACTION_UP:
currentFlag = getTouchFlag(x, y);
if (null != mListener && currentFlag == touchFlag && currentFlag != -1) {
if (currentFlag == BLACK_FLAG) {
mListener.onBlackClick();
} else if (currentFlag == WRITE_FLAG) {
mListener.onWriteClick();
}
}
touchFlag = currentFlag = -1;
break;
case MotionEvent.ACTION_CANCEL:
touchFlag = currentFlag = -1;
break;
}
Log.e("currentFlag", "-->" + currentFlag);
return true;
}
/**
* 判断落在哪个区域
*/
private int getTouchFlag(int x, int y) {
if (blackRegion.contains(x, y)) {
return BLACK_FLAG;
} else if (whiteRegion.contains(x, y)) {
return WRITE_FLAG;
}
return -1;
}
public void setListener(TaiJiListener mListener) {
this.mListener = mListener;
}
/**
* 设置触摸监听
*/
public interface TaiJiListener {
void onBlackClick();
void onWriteClick();
}
}
源代码
推荐文章
Android小练习——Path绘制不规则图形的点击
Android自定义view画五星红旗
Android绘制(二):来用Path绘出想要的图形吧!