Android用Canvas画一个折线图,并加以简单封装,2021吊打面试官系列

}

下面来简单封装一下


1.首先提供给外界输入数据的方法:

public void setChartdate(String[] xdate, int[] ydate, float[] linedate) {

this.xdate = xdate; //x轴坐标

this.ydate = ydate; //y轴坐标

this.linedate = linedate; //坐标点的y轴上的位置

}

2.进行数据为空判断和越界判断

if (xdate.length!=0&&ydate.length!=0&&linedate.length!=0&&xdate.length>=linedate.length){

if (yMaxdata()>=lineMaxdata()){

drawAxis(canvas);

}

}

其中yMaxdata(),lineMaxdata()方法作用为取ydate与linedate中的最大值

3.将所有写死的数据与传进来的数据产生联系。

private void drawDaxes(Canvas canvas, Paint p) {

//开始y绘制坐标系

canvas.drawLine(widthCriterion, hightCriterion, widthCriterion, hightCriterion * (yCopies - 1), p);

//绘制y角

canvas.drawLine(widthCriterion - minCriterion, hightCriterion + minCriterion, widthCriterion + 2, hightCriterion, p);

canvas.drawLine(widthCriterion, hightCriterion, widthCriterion + minCriterion - 2, hightCriterion + minCriterion, p);

//开始x绘制坐标系

canvas.drawLine(widthCriterion - 4, hightCriterion * (yCopies - 1), widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1), p);

//绘制x角

canvas.drawLine(widthCriterion * (xCopies - 1) - minCriterion, hightCriterion * (yCopies - 1) - minCriterion, widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1) + 2, p);

canvas.drawLine(widthCriterion * (xCopies - 1) - minCriterion, hightCriterion * (yCopies - 1) + minCriterion, widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1) - 2, p);

}

private void drawAxispoint(Canvas canvas, Paint p) {

textFont = widthCriterion / 5 * 2;

Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);

p.setTypeface(font);

p.setTextSize(textFont);

//画x轴数据

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

String text = xdate[i];

int stringWidth = (int) p.measureText(text); //文本长度

canvas.drawText(text, (i + 1) * widthCriterion - stringWidth / 2, hightCriterion * (yCopies - 1) + textFont, p);// 画文本

}

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

String text = String.valueOf(ydate[i]);

int stringWidth = (int) p.measureText(text);

//文本长度

if (i == 0) {

} else {

canvas.drawText(text, widthCriterion - textFont-stringWidth, hightCriterion * (yCopies - 1) - i * hightCriterion + stringWidth / 2, p);// 画文本

}

}

}

private void drawbrokenLine(Canvas canvas, Paint p) {

float line=(hightCriterion * (yCopies - 1)-hightCriterion*2)/ydate[ydate.length-1];

for (int i = 0; i

float height=hightCriterion * (yCopies-1)-line*linedate[i];

if (i!=linedate.length-1){

float elseheight=hightCriterion * (yCopies-1)-line*linedate[i+1];

canvas.drawLine(widthCriterion*(i+1),height , widthCriterion * (i+2), elseheight, p);

canvas.drawCircle(widthCriterion*(i+1), height, 10, p);

}else{

float endheight=hightCriterion * (yCopies-1)-line*linedate[linedate.length-1];

canvas.drawCircle(widthCriterion*(i+1), endheight, 10, p);

}

}

}

现在就可以根据给到的数据动态绘制简单折线图

接下来看效果

在Activity中找到控件后,调用控件的setChartdate()方法;

数据如下:

private String[] xdata={“0”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”};

private int[] yfata={0,10,20,30,40,50,60,70};

private float[] linedata={5,10,6,30,5,62.5f,6,2,};

传入数据:

linechartview.setChartdate(xdata,yfata,linedata);

效果图如下:

在这里插入图片描述

封装后java代码如下

public class LineChartView extends View {

private int minCriterion;

private int hightCriterion;

private int widthCriterion;

private int canvasHeight;

private int canvasWidth;

private int textFont;

private String[] xdate;

private int[] ydate;

private float[] linedate;

private int xCopies;

private float yCopies;

public void setChartdate(String[] xdate, int[] ydate, float[] linedate) {

this.xdate = xdate;

this.ydate = ydate;

this.linedate = linedate;

}

public LineChartView(Context context) {

super(context);

}

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

super(context, attrs);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (xdate.length!=0&&ydate.length!=0&&linedate.length!=0&&xdate.length>=linedate.length){

if (yMaxdata()>=lineMaxdata()){

drawAxis(canvas);

}

}

}

//绘制

private void drawAxis(Canvas canvas) {

xCopies = xdate.length + 2;

yCopies = ydate.length + 2;

Paint daxesPaint, axispointPaint, brokenLinePaint;

//画布宽度

canvasWidth = canvas.getWidth();

//画布高度

canvasHeight = canvas.getHeight();

widthCriterion = canvasWidth / xCopies;

hightCriterion = (int) (canvasHeight / yCopies);

minCriterion = widthCriterion > hightCriterion ? hightCriterion / 2 : widthCriterion / 2;

//开始绘制底层背景

daxesPaint = new Paint();

daxesPaint.setColor(Color.BLACK);

daxesPaint.setAntiAlias(true); //去掉锯齿效果

daxesPaint.setStrokeWidth(7.0f);

drawDaxes(canvas, daxesPaint);

//开始绘制坐标点

axispointPaint = daxesPaint;

drawAxispoint(canvas, axispointPaint);

//开始绘制折线和线上的点

brokenLinePaint=axispointPaint;

brokenLinePaint.setStrokeWidth(5.0f);

drawbrokenLine(canvas,brokenLinePaint);

}

private void drawDaxes(Canvas canvas, Paint p) {

//开始y绘制坐标系

canvas.drawLine(widthCriterion, hightCriterion, widthCriterion, hightCriterion * (yCopies - 1), p);

//绘制y角

canvas.drawLine(widthCriterion - minCriterion, hightCriterion + minCriterion, widthCriterion + 2, hightCriterion, p);

canvas.drawLine(widthCriterion, hightCriterion, widthCriterion + minCriterion - 2, hightCriterion + minCriterion, p);

//开始x绘制坐标系

canvas.drawLine(widthCriterion - 4, hightCriterion * (yCopies - 1), widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1), p);

//绘制x角

canvas.drawLine(widthCriterion * (xCopies - 1) - minCriterion, hightCriterion * (yCopies - 1) - minCriterion, widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1) + 2, p);

canvas.drawLine(widthCriterion * (xCopies - 1) - minCriterion, hightCriterion * (yCopies - 1) + minCriterion, widthCriterion * (xCopies - 1), hightCriterion * (yCopies - 1) - 2, p);

}

private void drawAxispoint(Canvas canvas, Paint p) {

textFont = widthCriterion / 5 * 2;

Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);

p.setTypeface(font);

p.setTextSize(textFont);

//画x轴数据

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

String text = xdate[i];

int stringWidth = (int) p.measureText(text); //文本长度

canvas.drawText(text, (i + 1) * widthCriterion - stringWidth / 2, hightCriterion * (yCopies - 1) + textFont, p);// 画文本

}

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

String text = String.valueOf(ydate[i]);

int stringWidth = (int) p.measureText(text);

//文本长度

if (i == 0) {

} else {

canvas.drawText(text, widthCriterion - textFont-stringWidth, hightCriterion * (yCopies - 1) - i * hightCriterion + stringWidth / 2, p);// 画文本

}

}

}

private void drawbrokenLine(Canvas canvas, Paint p) {

float line=(hightCriterion * (yCopies - 1)-hightCriterion*2)/ydate[ydate.length-1];

for (int i = 0; i

float height=hightCriterion * (yCopies-1)-line*linedate[i];

if (i!=linedate.length-1){

float elseheight=hightCriterion * (yCopies-1)-line*linedate[i+1];

canvas.drawLine(widthCriterion*(i+1),height , widthCriterion * (i+2), elseheight, p);

canvas.drawCircle(widthCriterion*(i+1), height, 10, p);

}else{

float endheight=hightCriterion * (yCopies-1)-line*linedate[linedate.length-1];

canvas.drawCircle(widthCriterion*(i+1), endheight, 10, p);

}

}

}

private float yMaxdata(){

float max = 0;

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

if (ydate[i] > max) {

max = ydate[i];

}

}

return max;

}

最后

在此为大家准备了四节优质的Android高级进阶视频:

架构师项目实战——全球首批Android开发者对Android架构的见解

链接:GitHub 免费获取!

附相关架构及资料

Android用Canvas画一个折线图,并加以简单封装,2021吊打面试官系列_第1张图片

max = 0;

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

if (ydate[i] > max) {

max = ydate[i];

}

}

return max;

}

最后

在此为大家准备了四节优质的Android高级进阶视频:

架构师项目实战——全球首批Android开发者对Android架构的见解

链接:GitHub 免费获取!

附相关架构及资料

[外链图片转存中…(img-7bZc5KGi-1643783639591)]

领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

你可能感兴趣的:(程序员,架构,移动开发,android)