1、自定义view折线图分析自定义view折线图绘制折线图预览图绘制这个折线图需要都需要哪些步骤?一、如何绘制X和Y轴。注意:绘制线用到的是path,而绘制X和Y轴,我们需要知道三个坐标,这里我们用的是 canvas.drawPath(mPath,linePaint);1、我们来分析下,我们想知道三个坐标,那么这三个坐标是多少呢,我们该怎么计算呢?答:这里,我是在onSizeChanged()方法中获取到了父类控件的宽度,然后把宽度分成16份,例如,下方的上下左右四个分别如下: lift = viewSize*(1/16f); top = viewSize*(1/16f); right = vie
2、wSize*(15/16f); buttom = viewSize*(8/16f);2、这三个坐标我们有了,那就好办了,我们根据这四个参数值,就可以知道我们上面三个坐标点的坐标,在draw()方法中,连接这三个点即可: private void drawXY(Canvas canvas) /* * 第三步,我们来通过viewSize尺寸来获取三个坐标点 * 第一个(X,Y)-(lift,top) * 第二个(X,Y)-(lift,button) * 第三个个(X,Y)-(right,buttom) * */ mPath.moveTo(lift, top); mPath.lineTo(lift,
3、 buttom); mPath.lineTo(right,buttom); /使用Path链接这三个坐标 canvas.drawPath(mPath,linePaint); / 释放画布 canvas.restore(); 3、我们最后,在X,Y轴写个文字,那么我们需要知道X,Y这两个文字的坐标是多少?如图:答:因为我们已经知道lift,right,top, buttom。其实我们就可计算出来他们的坐标了。其实Y轴的坐标只是向右移动一点即可(lift+num,top),x的坐标向下移动一点即可(right,top+num),其中num是你移动多少。自己可以合理调试private void dr
4、awXYelement(Canvas canvas) / 锁定画布 canvas.save(); mTextPaint.setTextSize(36);/文字大小 /* * Y轴文字提示 * drawText(String ,x,y,TextPaint) * (lift,top) * */ mTextPaint.setTextAlign(Paint.Align.LEFT);/左对齐 canvas.drawText(Y,lift+20,top,mTextPaint); /* * X轴文字提示 * drawText(String ,right,buttom,TextPaint) * */ mTex
5、tPaint.setTextAlign(Paint.Align.RIGHT);/右对齐 canvas.drawText(X,right,buttom+50,mTextPaint); / 释放画布 canvas.restore(); 我们在main的xml引用此类 编译一下效果:4、附上全部代码package .polylinedemo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import an
6、droid.graphics.Path;import android.text.TextPaint;import android.util.AttributeSet;import android.util.Log;import android.view.View;/* * Created by ENZ on 2016/11/25. * 绘制自定义view折线图 * 第一步:绘制X和Y轴,那么我们需要什么准备呢? */public class XYView01 extends View private int viewSize;/获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确)
7、private Paint linePaint;/ 线条画笔和点画笔 private Path mPath;/ 路径对象 private TextPaint mTextPaint;/ 文字画笔 float lift ; float top ; float right ; float buttom ; float PathY_X ; float PathY_Y ; float PathX_X ; float PathX_Y ; public XYView01(Context context, AttributeSet attrs) super(context, attrs); /第一步,初始化对
8、象 linePaint = new Paint(); linePaint.setColor(Color.YELLOW);/线条的颜色 linePaint.setStrokeWidth(8);/线条的宽度 linePaint.setAntiAlias(true);/取消锯齿 linePaint.setStyle(Paint.Style.STROKE);/粗线 /初始化Path mPath = new Path(); mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FL
9、AG); mTextPaint.setColor(Color.WHITE); public XYView01(Context context) super(context); Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) / 在我们没学习测量控件之前强制宽高一致 super.onMeasure(widthMeasureSpec, widthMeasureSpec); Override protected void onSizeChanged(int w, int h, int old
10、w, int oldh) super.onSizeChanged(w, h, oldw, oldh); /第二步骤,我们在这里获取每个用到的坐标点和尺寸 viewSize = w;/获取空间的尺寸, Log.i(Text,viewSize:+viewSize); /这个是我们上下左右需要用到的坐标点 lift = viewSize*(1/16f); top = viewSize*(1/16f); right = viewSize*(15/16f); buttom = viewSize*(8/16f); Override protected void onDraw(Canvas canvas)
11、super.onDraw(canvas); / 锁定画布 canvas.save(); /定义一个绘制X,Y轴的方法 drawXY(canvas); /绘制X和Y轴上的提示文字 drawXYelement(canvas); private void drawXY(Canvas canvas) /* * 第三步,我们来通过viewSize尺寸来获取三个坐标点 * 第一个(X,Y)-(lift,top) * 第二个(X,Y)-(lift,button) * 第三个个(X,Y)-(right,buttom) * */ mPath.moveTo(lift, top); mPath.lineTo(lif
12、t, buttom); mPath.lineTo(right,buttom); /使用Path链接这三个坐标 canvas.drawPath(mPath,linePaint); / 释放画布 canvas.restore(); private void drawXYelement(Canvas canvas) / 锁定画布 canvas.save(); mTextPaint.setTextSize(36);/文字大小 /* * Y轴文字提示 * drawText(String ,x,y,TextPaint) * (lift,top) * */ mTextPaint.setTextAlign(P
13、aint.Align.LEFT);/左对齐 canvas.drawText(Y,lift+20,top,mTextPaint); /* * X轴文字提示 * drawText(String ,right,buttom,TextPaint) * */ mTextPaint.setTextAlign(Paint.Align.RIGHT);/右对齐 canvas.drawText(X,right,buttom+50,mTextPaint); / 释放画布 canvas.restore(); 1、我们绘制X和Y轴区域的子网格,我们需要知道他们范围? Y轴上的最大范围=(buttom - top) ;
14、X轴的最大范围=(right - lift) ; 2、在这个范围我们需要分为多少个端即有几个数据?每一段间距事是多少? / 假如我们有八条数据 int count = pointFs.size(); / 计算横纵坐标刻度间隔 spaceY =(buttom - top) / count; spaceX =(right - lift) / count;3、最大值和最小值是多少? / 计算横轴数据最大值 maxX = 0; for (int i = 0; i count; i+) if (maxX pointFs.get(i).x) maxX = pointFs.get(i).x;/X轴最大坐标
15、Log.i(Text,maxX:-+maxX); / 计算横轴最近的能被count整除的值 int remainderX = (int) maxX) % divisor; maxX = remainderX = 0 ? (int) maxX) : divisor - remainderX + (int) maxX); / 计算纵轴数据最大值 maxY = 0; for (int i = 0; i count; i+) if (maxY top; y -= spaceY) Log.i(Text,y+y); for (float x = lift; x right; x += spaceX) Lo
16、g.i(Text,x+x); /* * 绘制纵向线段 */ if (y = top + spaceY) canvas.drawLine(x, y, x, y + spaceY * (count - 1), linePaint); /* * 绘制横向线段 */ if (x = right - spaceX) canvas.drawLine(x, y, x - spaceX * (count - 1), y, linePaint); 5、全部代码,只是多了一个方法drawLines(canvas);package .polylinedemo;import android.content.Conte
17、xt;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PointF;import android.text.TextPaint;import android.util.AttributeSet;import android.util.Log;import android.view.View;import java.util.ArrayList;import
18、java.util.List;import java.util.Random;/* * Created by ENZ on 2016/11/25. * 绘制自定义view折线图 * 第一步:绘制X和Y轴,那么我们需要什么准备呢? */public class XYView02 extends View private int viewSize;/获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确) private Paint linePaint;/ 线条画笔和点画笔 private Path mPath;/ 路径对象 private TextPaint mTextPaint;/ 文
19、字画笔 private List pointFs = new ArrayList();/ 数据列表 private float rulerX, rulerY;/ xy轴向刻度 /上下左右坐标点 private float lift ; private float top ; private float right ; private float buttom ; /Y轴文字坐标点 private float PathY_X ; private float PathY_Y ; /X轴文字坐标点 private float PathX_X ; private float PathX_Y ; pri
20、vate float maxX;/x轴最大值 private float maxY;/Y轴最大值 private float spaceX, spaceY;/ 刻度间隔 public XYView02(Context context, AttributeSet attrs) super(context, attrs); /第一步,初始化对象 linePaint = new Paint(); linePaint.setColor(Color.YELLOW);/线条的颜色 linePaint.setStrokeWidth(8);/线条的宽度 linePaint.setAntiAlias(true)
21、;/取消锯齿 linePaint.setStyle(Paint.Style.STROKE);/粗线 /初始化Path mPath = new Path(); mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG); mTextPaint.setColor(Color.WHITE); /模拟数据 initData(); public XYView02(Context context) super(context); Override protected void
22、onMeasure(int widthMeasureSpec, int heightMeasureSpec) / 在我们没学习测量控件之前强制宽高一致 super.onMeasure(widthMeasureSpec, widthMeasureSpec); Override protected void onSizeChanged(int w, int h, int oldw, int oldh) super.onSizeChanged(w, h, oldw, oldh); /第二步骤,我们在这里获取每个用到的坐标点和尺寸 viewSize = w;/获取空间的尺寸, Log.i(Text,v
23、iewSize:+viewSize); /这个是我们上下左右需要用到的坐标点 lift = viewSize*(1/16f); top = viewSize*(1/16f); right = viewSize*(15/16f); buttom = viewSize*(8/16f); /下面是绘制X,Y轴提示文字 /* * Y轴(PathY_X,PathY_Y) * */ PathY_X = viewSize*2/16; PathY_Y = viewSize*1/16; /* * X轴(PathX_X,PathX_Y) * */ PathX_X = viewSize*15/16f; PathX_
24、Y = viewSize*9/16f; Override protected void onDraw(Canvas canvas) super.onDraw(canvas); / 锁定画布 canvas.save(); /定义一个绘制X,Y轴的方法 drawXY(canvas); /绘制X和Y轴上的提示文字 drawXYelement(canvas); private void initData() Random random = new Random(); pointFs = new ArrayList(); for (int i = 0; i 8; i+) PointF pointF =
25、new PointF(); pointF.x = (float) (random.nextInt(100) * i); pointF.y = (float) (random.nextInt(100) * i); pointFs.add(pointF); private void drawXY(Canvas canvas) /* * 第三步,我们来通过viewSize尺寸来获取三个坐标点 * 第一个(X,Y)-(lift,top) * 第二个(X,Y)-(lift,button) * 第三个个(X,Y)-(right,buttom) * */ mPath.moveTo(lift, top); m
26、Path.lineTo(lift, buttom); mPath.lineTo(right,buttom); /使用Path链接这三个坐标 canvas.drawPath(mPath,linePaint); /-我们在这里添加一个绘制网格的方法- drawLines(canvas); / 释放画布 canvas.restore(); private void drawLines(Canvas canvas) / 重置线条画笔,因为是细线,所有我这里设置了2。 linePaint.setStrokeWidth(2); / 假如我们有八条数据 int count = pointFs.size();
27、 / 计算横纵坐标刻度间隔 spaceY =(buttom - top) / count; spaceX =(right - lift) / count; Log.i(Text,spaceY:-+spaceY); Log.i(Text,spaceX:-+spaceX); / 计算除数的值为数据长度减一,8个数据,7条线。 int divisor = count - 1; Log.i(Text,divisor:-+divisor); / 计算横轴数据最大值 maxX = 0; for (int i = 0; i count; i+) if (maxX pointFs.get(i).x) maxX = pointFs.get(i).x;/X轴最大坐标 Log.i(Text,maxX:-+maxX); / 计算横轴最近的能被count整除的值 int remainderX = (int) maxX) % divisor; maxX = remainderX = 0 ? (int)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1