android 自定义画图片格式,Android自定义View七(复习基本图形的绘制)

基本图形的绘制

public class CanvasLearn extends View {

private Paint mPaint;

public CanvasLearn(Context context) {

this(context, null);

}

public CanvasLearn(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public CanvasLearn(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initPaint();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

setCanvasColor(canvas);

// drawPoint(canvas);

// drawLine(canvas);

// drawRectOrRectF(canvas);

// drawRoundRect(canvas);

// drawOval( canvas);

// drawCircle(canvas);

// drawAre(canvas);

}

/**

* 1、初始化画笔

*/

private void initPaint() {

mPaint = new Paint();

mPaint.setStrokeWidth(10);//设置画笔宽度

mPaint.setColor(Color.RED);//设置画笔颜色

mPaint.setStyle(Paint.Style.FILL);//设置画布类型(Fill填充STROKE扫边 FILL_AND_STROKE填充和扫边)

}

/**

* 2、设置画布颜色

*/

private void setCanvasColor(Canvas canvas) {

canvas.drawColor(Color.WHITE);

}

/**

* 3、绘制点及多个点

*/

private void drawPoint(Canvas canvas) {

mPaint.setStrokeCap(Paint.Cap.ROUND);//设置圆角触笔是点变成圆点

mPaint.setColor(Color.BLUE);

canvas.drawPoint(100, 100, mPaint);//绘制一个点

mPaint.setColor(Color.GREEN);//设置画笔颜色区分

canvas.drawPoints(new float[]{500, 200, 500, 400, 500, 600}, mPaint);//根据多个坐标绘制多个点

}

/**

* 4、绘制直线及多个线段

*/

private void drawLine(Canvas canvas) {

mPaint.setColor(Color.BLUE);

canvas.drawLine(100, 100, 300, 100, mPaint);//绘制一条线段(参数是其实点到x、y轴坐标到结束到x、y轴坐标)

mPaint.setColor(Color.GREEN);//设置画笔颜色区分

canvas.drawLines(new float[]{200, 200, 300, 200, 200, 400, 500, 400}, mPaint);

}

/**

* 5、绘制矩形

* Rect与RectF的区别是精度不同,Rect是int型,Rect是float型

*/

private void drawRectOrRectF(Canvas canvas) {

//第一种

canvas.drawRect(100, 100, 800, 200, mPaint);

//第二种

Rect rect = new Rect(100, 300, 800, 400);

canvas.drawRect(rect, mPaint);

//第三种

RectF rectF = new RectF(100, 500, 800, 600);

canvas.drawRect(rectF, mPaint);

}

/**

* 绘制圆角矩形

*/

private void drawRoundRect(Canvas canvas) {

//第一种

RectF rectF = new RectF(100, 100, 800, 400);

canvas.drawRoundRect(rectF, 30, 30, mPaint);

//第二种方法在API21的时候才可以用,建议用第一种

//设置圆弧角度rx>矩形宽度/2(350) ry>矩形高度/2 (200)时都可以画成椭圆

canvas.drawRect(100,600,800,1000,mPaint);

mPaint.setColor(Color.GRAY);

canvas.drawRoundRect(100,600,800,1000,350,250,mPaint);

}

/**

* 绘制椭圆

*/

private void drawOval(Canvas canvas){

//第一种

RectF rectF=new RectF(100,100,800,400);

canvas.drawOval(rectF,mPaint);

//第二种不建议使用21以上才有

canvas.drawOval(100,500,800,900,mPaint);

}

/**

* 绘制一个圆心坐标在(500,500),半径为300 的圆

*/

private void drawCircle(Canvas canvas){

canvas.drawCircle(500,500,300,mPaint);

}

/**

* 绘制圆弧

* 参数介绍startAngle 开始角度 sweepAngle 结束角度 useCenter 是否使用中心

*/

private void drawAre(Canvas canvas){

RectF rectF=new RectF(100,100,500,500);

mPaint.setColor(Color.GRAY);

canvas.drawRect(rectF,mPaint);

mPaint.setColor(Color.GREEN);

canvas.drawArc(rectF,0,90,false,mPaint);

RectF rectF1=new RectF(100,600,500,1100);

mPaint.setColor(Color.GRAY);

canvas.drawRect(rectF1,mPaint);

mPaint.setColor(Color.GREEN);

canvas.drawArc(rectF1,0,90,true,mPaint);

}

简单的绘制一个圆饼图

public class PieView extends View {

private int[] datas = {20, 60, 80, 10, 50};//数据

private int[] colors = {Color.BLACK, Color.GREEN, Color.GRAY, Color.RED, Color.BLUE};//颜色

private int mWidth, mHeight; //宽高

private float mRadius; //半径

private RectF rectF;//圆饼图区域

private Paint mPaint = new Paint();//画笔

public PieView(Context context) {

this(context, null);

}

public PieView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public PieView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mPaint.setStyle(Paint.Style.FILL);

mPaint.setAntiAlias(true);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mHeight = h;

mWidth = w;

mRadius = Math.min(mHeight, mWidth) / 2 * 0.8f;

rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(mWidth / 2, mHeight / 2);

drawPie(canvas);

}

/**

*绘制圆饼图

*/

private void drawPie(Canvas canvas) {

float sumValues = 0;

for (int i = 0; i < datas.length; i++) {

sumValues += datas[i];

}

float startAngle = 0;//初始角度

for (int i = 0; i < datas.length; i++) {

mPaint.setColor(colors[i]);

float percentage = datas[i] / sumValues ;

float angle=percentage*360;

canvas.drawArc(rectF,startAngle,angle,true,mPaint);

startAngle += angle;

}

}

}

5476461d5085

Screenshot_1489053291.png

根据Path图形的绘制

public class PathLearn extends View {

private Paint mPaint;

private int mWidth, mHeight;

public PathLearn(Context context) {

this(context, null);

}

public PathLearn(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public PathLearn(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView();

}

private void initView() {

mPaint = new Paint();

mPaint.setStyle(Paint.Style.FILL);

mPaint.setColor(Color.GREEN);

mPaint.setAntiAlias(true);

mPaint.setStrokeWidth(10);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mWidth = w;

mHeight = h;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(mWidth / 2, mHeight / 2);

// canvas.scale(1,-1);//翻转y轴坐标

drawAllPoint(canvas);

drawPathXY(canvas);

// drawPathLine(canvas);

// drawPathRect(canvas);

// drawPathAll(canvas);

// drawPathaddArc(canvas);

}

//------------moveTo、 setLastPoint、 lineTo 和 close-----------------

/**

* 利用path绘制坐标和箭头

* moveTo 设置path起点

* lineTo path直线到终点

*/

private void drawPathXY(Canvas canvas) {

Path mPath = new Path();

mPaint.setStrokeWidth(1);

mPaint.setColor(Color.BLACK);

mPaint.setStyle(Paint.Style.STROKE);

//x轴与箭头

mPath.moveTo(-mWidth / 2 * 0.8f, 0);

mPath.lineTo(mWidth / 2 * 0.8f, 0);

mPath.lineTo(mWidth / 2 * 0.8f * 0.95f, -mWidth / 2 * 0.8f * 0.05f);

mPath.moveTo(mWidth / 2 * 0.8f, 0);

mPath.lineTo(mWidth / 2 * 0.8f * 0.95f, mWidth / 2 * 0.8f * 0.05f);

//y轴

mPath.moveTo(0, -mHeight / 2 * 0.8f);

mPath.lineTo(0, mHeight / 2 * 0.8f);

//y轴箭头

mPath.moveTo(mWidth / 2 * 0.8f * 0.05f, mHeight / 2 * 0.8f - mWidth / 2 * 0.8f * 0.05f);

mPath.lineTo(0, mHeight / 2 * 0.8f);

mPath.lineTo(-mWidth / 2 * 0.8f * 0.05f, mHeight / 2 * 0.8f - mWidth / 2 * 0.8f * 0.05f);

canvas.drawPath(mPath, mPaint);

}

/**

* setLastPoint() 重置上一次操作的最后一个点

* close() 方法用于连接当前最后一个点和最初的一个点

*/

private void drawPathLine(Canvas canvas) {

Path mPath = new Path();

mPaint.setColor(Color.RED);

mPaint.setStrokeWidth(5);

mPath.lineTo(200, 200);

// mPath.moveTo(200,100);

mPath.setLastPoint(200, 100);

mPath.lineTo(200, 0);

mPath.close();

canvas.drawPath(mPath, mPaint);

}

/**

* 用原点和四个端点

*/

private void drawAllPoint(Canvas canvas) {

mPaint.setStrokeWidth(20);

mPaint.setStrokeCap(Paint.Cap.ROUND);

canvas.drawPoints(new float[]{0, 0, mWidth / 2 * 0.8f, 0, -mWidth / 2 * 0.8f, 0, 0, mHeight / 2 * 0.8f, 0, -mHeight / 2 * 0.8f}, mPaint);

}

//------------addCircle() addOval() addRect() addRoundRect() 参数Path.Direction cw 顺时针 ccw 逆时针-----------------

/**

* path绘制矩形

* setLastPoint(-300,300)修改最后点的位置

*/

private void drawPathRect(Canvas canvas) {

Path path = new Path();

// path.addRect(-200, -200, 200, 200, Path.Direction.CW);

path.addRect(-200, -200, 200, 200, Path.Direction.CCW);

// path.setLastPoint(-300,300);

canvas.drawPath(path, mPaint);

}

/**

* patn绘制其他基本图形

* addPath (Path src)将两个Path合并成为一个

* addPath (Path src, float dx, float dy) 进行了位移之后再添加进当前path中

* addPath (Path src, Matrix matrix) 添加到当前path之前先使用Matrix进行变换

*/

private void drawPathAll(Canvas canvas) {

Path path = new Path();

Path path1 = new Path();

Path path2 = new Path();

// mPaint.setStyle(Paint.Style.FILL);

path.addCircle(0, 0, 200, Path.Direction.CW);

// path.setLastPoint(-300,300);

path1.addOval(-300, -200, 300, 200, Path.Direction.CW);

// path.setLastPoint(-300,300);

path2.addRoundRect(-200, -200, 200, 200, 30, 30, Path.Direction.CW);

// path.setLastPoint(-300,300);

path.addPath(path1, 0, -300);

path.addPath(path2, 0, 300);

canvas.drawPath(path, mPaint);

}

//------------addArc与arcTo-----------------

/**

* public void addArc (RectF oval, float startAngle, float sweepAngle)

* public void arcTo (RectF oval, float startAngle, float sweepAngle)

* public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

* oval 圆弧的外切矩形。

* startAngle 开始角度

* sweepAngle 扫过角度(-360 <= sweepAngle <360)

* forceMoveTo 是否强制使用MoveTo

* addArc 直接添加一个圆弧到path中

* arcTo 添加一个圆弧到path,如果圆弧的起点和上次最后一个坐标点不相同,就连接两个点

* forceMoveTo true 将最后一个点移动到圆弧起点,即不连接最后一个点与圆弧起点

* firceMoveTo false 不移动,而是连接最后一个点与圆弧起点

*/

/**

* 圆弧

*/

private void drawPathaddArc(Canvas canvas) {

Path path = new Path();

path.lineTo(100, -100);

RectF rectF = new RectF(0, -200, 200, 0);

// path.addArc(rectF,0,280);

// path.arcTo(rectF,0,270,false);

path.arcTo(rectF, 0, 270, true);

path.offset(0,300,path);

canvas.drawPath(path, mPaint);

}

//------------isEmpty、 isRect、isConvex、 set 和 offset-----------------

/**

* isEmpty() 判断path中是否包含内容 true-无内容 false-有内容

* isRect() 判断path是否是一个矩形,如果是一个矩形的话,会将矩形的信息存放进参数rect中

* set() 将新的path赋值到现有path

* offset() 就是对path进行一段平移

*/

雷达图的绘制

public class RadarView extends View {

private int count = 8;//数据个数

private float angle = (float) (Math.PI * 2 / count);//每个数据的平均弧度

private float radius; //网络最大半径

private int centerX; //中心X坐标

private int centerY; //中心Y坐标

private String[] titles = {"1", "2", "3", "4", "5", "6","7","8"};

private double[] data = {20, 30, 40, 50, 60, 70,80,90}; //各维度分值

private float maxValues = 100; //数据最大值

private Paint radarPaint = new Paint(); //雷达图画笔

private Paint valuePaint = new Paint(); //网格图画笔

private Paint textPaint = new Paint(); //文本画笔

private Paint xyPaint = new Paint(); //坐标画笔

private int mWidth, mHeight;

public RadarView(Context context) {

this(context, null);

}

public RadarView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView();

}

//初始化数据

private void initView() {

//设置雷达画笔属性

radarPaint.setStyle(Paint.Style.FILL_AND_STROKE);

radarPaint.setColor(Color.GREEN);

radarPaint.setAntiAlias(true);

//设置网格图画笔属性

valuePaint.setStyle(Paint.Style.STROKE);

valuePaint.setColor(Color.BLUE);

valuePaint.setAntiAlias(true);

//设置文本画笔属性

textPaint.setStyle(Paint.Style.FILL);

textPaint.setColor(Color.BLACK);

textPaint.setTextSize(30);

textPaint.setAntiAlias(true);

//设置坐标画笔属性

xyPaint.setColor(Color.RED);

xyPaint.setAntiAlias(true);

xyPaint.setStyle(Paint.Style.STROKE);

xyPaint.setStrokeWidth(4);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mWidth = w;

mHeight = h;

radius = Math.min(mWidth, mHeight) / 2 * 0.8f;

centerY = h / 2;

centerX = w / 2;

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(centerX, centerY);

// drawXY(canvas);

drawValues(canvas);

drawCover(canvas);

}

/**

* 画坐标

*/

private void drawXY(Canvas canvas) {

Path mPath = new Path();

//x轴与箭头

mPath.moveTo(-mWidth / 2 * 0.95f, 0);

mPath.lineTo(mWidth / 2 * 0.95f, 0);

mPath.lineTo(mWidth / 2 * 0.95f * 0.95f, -mWidth / 2 * 0.95f * 0.05f);

mPath.moveTo(mWidth / 2 * 0.95f, 0);

mPath.lineTo(mWidth / 2 * 0.95f * 0.95f, mWidth / 2 * 0.95f * 0.05f);

//y轴

mPath.moveTo(0, -mHeight / 2 * 0.95f);

mPath.lineTo(0, mHeight / 2 * 0.95f);

//y轴箭头

mPath.moveTo(mWidth / 2 * 0.95f * 0.05f, mHeight / 2 * 0.95f - mWidth / 2 * 0.95f * 0.05f);

mPath.lineTo(0, mHeight / 2 * 0.95f);

mPath.lineTo(-mWidth / 2 * 0.95f * 0.05f, mHeight / 2 * 0.95f - mWidth / 2 * 0.95f * 0.05f);

canvas.drawPath(mPath, xyPaint);

}

/**

* 绘制网格图和文本

*/

private void drawValues(Canvas canvas) {

Path path = new Path();//多边形path

Path linePath = new Path();//直线Path

float r = radius / count - 1;//设置网格之间的间距

Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();

float textHeight = (-fontMetrics.ascent - fontMetrics.descent);//文本高度

for (int j = 0; j < count; j++) {

float newR = r * j;

path.reset();

for (int i = 0; i < count; i++) {

float x = (float) (newR * Math.cos(angle * i));

float y = (float) (newR * Math.sin(angle * i));

if(j==count-1){

//绘制直线

linePath.reset();

linePath.moveTo(0, 0);

linePath.lineTo(x, y);

canvas.drawPath(linePath, valuePaint);

}

if (i == 0) {

path.moveTo(newR, 0);

} else {

path.lineTo(x, y);

}

}

path.close();

canvas.drawPath(path, valuePaint);

//绘制文本

float textX = (float) ((radius - r + textHeight / 2) * Math.cos(angle * j));

float textY = (float) ((radius - r + textHeight / 2) * Math.sin(angle * j));

float textWidth = textPaint.measureText(titles[j]);//文本长度

if (j == 0) {

canvas.drawText(titles[j], textX, textY + textHeight / 2, textPaint);

} else if (j == 1) {

canvas.drawText(titles[j], textX - textWidth / 2, textY + textHeight, textPaint);

} else if (j == 2) {

canvas.drawText(titles[j], textX - textWidth / 2, textY + textHeight, textPaint);

} else if (j == 3) {

canvas.drawText(titles[j], textX - textWidth, textY + textHeight / 2, textPaint);

} else if (j == 4) {

canvas.drawText(titles[j], textX - textWidth / 2, textY, textPaint);

} else {

canvas.drawText(titles[j], textX - textWidth / 2, textY, textPaint);

}

}

}

/**

* 绘制覆盖区域

*/

private void drawCover(Canvas canvas) {

Path path=new Path();

float r = radius / count - 1;//设置网格之间的间距

for(int i=0;i

double percent=data[i]/maxValues;

float x = (float) ((radius-r)*Math.cos(angle*i)*percent);

float y = (float) ((radius-r)*Math.sin(angle*i)*percent);

if(i==0){

path.moveTo(x,0);

}else{

path.lineTo(x,y);

}

//绘制小圆点

canvas.drawCircle(x,y,5,radarPaint);

// canvas.drawPoint(x,y,radarPaint);

}

path.close();

radarPaint.setStyle(Paint.Style.STROKE);

canvas.drawPath(path,radarPaint);

//绘制填充区域

radarPaint.setAlpha(105);

radarPaint.setStyle(Paint.Style.FILL_AND_STROKE);

canvas.drawPath(path,radarPaint);

}

}

效果

5476461d5085

Screenshot_1489048128.png

5476461d5085

Screenshot_1489049585.png

/**

* 根据path绘制饼图

*/

private void drawPathAcr(Canvas canvas) {

float outRadius = mRadius;

outRecF = new RectF(-outRadius, -outRadius, outRadius, outRadius);

float alphaRadius = mRadius * 0.6f;

alphaRecf = new RectF(-alphaRadius, -alphaRadius, alphaRadius, alphaRadius);

float inRadius = mRadius * 0.5f;

inRecF = new RectF(-inRadius, -inRadius, inRadius, inRadius);

if (mDatas.size() == 0) {

return;

}

canvas.rotate(drawStartAngle);

canvas.save();

float startAngle = 0;

for (PieChartBean ben : mDatas) {

float sweepAngle = ben.getPercentage();

outPaht.moveTo(0, 0);

outPaht.arcTo(outRecF, startAngle, sweepAngle);

inPaht.moveTo(0, 0);

inPaht.arcTo(inRecF, startAngle, sweepAngle);

alphaPaht.moveTo(0, 0);

alphaPaht.arcTo(alphaRecf, startAngle, sweepAngle);

pietPaht.op(outPaht, inPaht, Path.Op.DIFFERENCE);

alphaPiePaht.op(alphaPaht, inPaht, Path.Op.DIFFERENCE);

arcPaint.setColor(ben.getPieColor());

canvas.drawPath(pietPaht, arcPaint);

arcPaint.setAlpha(100);

arcPaint.setColor(Color.GRAY);

canvas.drawPath(alphaPiePaht, arcPaint);

outPaht.reset();

inPaht.reset();

alphaPaht.reset();

startAngle += sweepAngle;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值