}
下面来简单封装一下
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 <linedate.length; 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 <linedate.length; 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 免费获取!
附相关架构及资料
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进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
|