自定义view—折线图_第1页
自定义view—折线图_第2页
自定义view—折线图_第3页
自定义view—折线图_第4页
自定义view—折线图_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、自定义view折线图绘制折线图预览图绘制这个折线图需要都需要哪些步骤?一、如何绘制X和Y轴。注意:绘制线用到的是path,而绘制X和Y轴,我们需要知道三个坐标,这里我们用的是 canvas.drawPath(mPath,linePaint);1、我们来分析下,我们想知道三个坐标,那么这三个坐标是多少呢,我们该怎么计算呢?答:这里,我是在onSizeChanged()方法中获取到了父类控件的宽度,然后把宽度分成16份,例如,下方的上下左右四个分别如下: lift = viewSize*(1/16f); top = viewSize*(1/16f); right = viewSize*(15/16

2、f); 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, buttom); mP

3、ath.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 drawXYelement(

4、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引用此类 <.polylinedemo.XYView01 android:id="+id/My_XYView04" android:layout_width="wrap_content" android:layout_height="500dp" andr

6、oid:background="#8B7500" />编译一下效果:4、附上全部代码package .polylinedemo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.text.TextPaint;import android.util.AttributeSet;import an

7、droid.util.Log;import android.view.View;/* * Created by ENZ on 2016/11/25. * 绘制自定义view折线图 * 第一步:绘制X和Y轴,那么我们需要什么准备呢? */public class XYView01 extends View private int viewSize;/获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确) private Paint linePaint;/ 线条画笔和点画笔 private Path mPath;/ 路径对象 private TextPaint mTextPaint;/

8、文字画笔 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); /第一步,初始化对象 linePaint = new Paint(); linePaint.setColor(Color.YELLOW);/线条的颜色 linePaint.setStrokeWidth(

9、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_FLAG); mTextPaint.setColor(Color.WHITE); public XYView01(Context context) super(context); Over

10、ride protected void 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;/获

11、取空间的尺寸, 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) super.onDraw(canvas); / 锁定画布 canvas.save(); /定义一个绘制X,Y轴的方法 drawXY(ca

12、nvas); /绘制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(lift, buttom); mPath.lineTo(right,buttom); /使用Path链接这三个坐标 canvas.drawPa

13、th(mPath,linePaint); / 释放画布 canvas.restore(); private void drawXYelement(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,mTex

14、tPaint); /* * 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) ; X轴的最大范围=(right - lift) ; 2、在这个范围我们需要分为多少个端即有

15、几个数据?每一段间距事是多少? / 假如我们有八条数据 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轴最大坐标 Log.i("Text","maxX:

16、-"+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 < pointFs.get(i).y) maxY = pointFs.get(i).y; Log.i("Text","maxY:-&q

17、uot;+maxY); / 计算纵轴最近的能被count整除的值 int remainderY = (int) maxY) % divisor; Log.i("Text","remainderY:-"+remainderY);4、既然我们已经知道了最大值和最小值,也知道了间距,那么我么开始绘制,通过for循环来绘制Y轴,每绘制每一个Y轴的点,都会把X轴与之相交的点全部绘制。(自己可以在本子上画画图就容易理解了)例如下图 / 锁定画布并设置画布透明度为75% int sc = canvas.saveLayerAlpha(0, 0, canvas.getWi

18、dth(), canvas.getHeight(), 75, Canvas.ALL_SAVE_FLAG); / 绘制横纵线段 for (float y = buttom - spaceY; y > top; y -= spaceY) Log.i("Text","y"+y); for (float x = lift; x < right; x += spaceX) Log.i("Text","x"+x); /* * 绘制纵向线段 */ if (y = top + spaceY) canvas.drawLi

19、ne(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.Context;import android.graphics.Canvas;import android.graphics.Color;i

20、mport 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 java.util.List;import java.util.Random;/* * Created by ENZ on 201

21、6/11/25. * 绘制自定义view折线图 * 第一步:绘制X和Y轴,那么我们需要什么准备呢? */public class XYView02 extends View private int viewSize;/获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确) private Paint linePaint;/ 线条画笔和点画笔 private Path mPath;/ 路径对象 private TextPaint mTextPaint;/ 文字画笔 private List<PointF> pointFs = new ArrayList<>();

22、/ 数据列表 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 ; private float maxX;/x轴最大值 private float maxY;/

23、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);/取消锯齿 linePaint.setStyle(Paint.Style.STROK

24、E);/粗线 /初始化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 onMeasure(int widthMeasureSpec, int heightM

25、easureSpec) / 在我们没学习测量控件之前强制宽高一致 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","viewSize:"+viewSize);

26、 /这个是我们上下左右需要用到的坐标点 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_Y = viewSize*9/16f;

27、 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<PointF>(); for (int i = 0; i < 8; i+) PointF pointF =

28、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

29、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();

30、 / 计算横纵坐标刻度间隔 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); / 计算横轴数据最大

31、值 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) maxX) : divisor - remainderX + (int) maxX); / 计算纵轴

32、数据最大值 maxY = 0; for (int i = 0; i < count; i+) if (maxY < pointFs.get(i).y) maxY = pointFs.get(i).y; Log.i("Text","maxY:-"+maxY); / 计算纵轴最近的能被count整除的值 int remainderY = (int) maxY) % divisor; Log.i("Text","remainderY:-"+remainderY); if(remainderY = 0&

33、&maxY=0) maxY=0; else maxY=divisor - remainderY + (int) maxY); Log.i("Text","maxY11111111111:-"+maxY); / / 生成横轴刻度值/ rulerX = new floatcount;/ for (int i = 0; i < count; i+) / rulerXi = maxX / divisor * i;/ / Log.i("Text","rulerX:-"+rulerX);/ / 生成纵轴刻度值/

34、rulerY = new floatcount;/ for (int i = 0; i < count; i+) / rulerYi = maxY / divisor * i;/ / Log.i("Text","rulerY:-"+rulerY); / 锁定画布并设置画布透明度为75% int sc = canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), 75, Canvas.ALL_SAVE_FLAG); / 绘制横纵线段 for (float y = buttom

35、 - spaceY; y > top; y -= spaceY) Log.i("Text","y"+y); for (float x = lift; x < right; x += spaceX) Log.i("Text","x"+x); /* * 绘制纵向线段 */ if (y = top + spaceY) canvas.drawLine(x, y, x, y + spaceY * (count - 1), linePaint); /* * 绘制横向线段 */ if (x = right - spa

36、ceX) canvas.drawLine(x, y, x - spaceX * (count - 1), y, linePaint); / 还原画布 canvas.restoreToCount(sc); private void drawXYelement(Canvas canvas) / 锁定画布 canvas.save(); mTextPaint.setTextSize(36);/文字大小 /* * Y轴文字提示 * drawText(String ,x,y,TextPaint) * (lift,top) * */ mTextPaint.setTextAlign(Paint.Align.L

37、EFT);/左对齐 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、再根据我们绘制网格的点,来绘制我们的刻度 int num = 0;/用于给X轴赋值

38、 int num_y = 0;/用于给Y轴赋值 for (float y = buttom - spaceY; y > top; y -= spaceY) for (float x = lift; x < right; x += spaceX) mTextPaint.setTextSize(28); /* * 绘制横轴刻度数值 */ if (y = buttom - spaceY) canvas.drawText(""+index_xnum, x-12, buttom+(top/3), mTextPaint); Log.i("Text",&q

39、uot;num-"+num); /* * 绘制纵轴刻度数值 * 简单来说就是,Y轴上的坐标点,X轴是恒定不变的,但是Y轴是变化的(buttom - 间距)+10的距离向上绘制 */ if (x = lift) canvas.drawText(""+index_ynum_y, lift - (lift/2), y + 10, mTextPaint); Log.i("Text","lift:"+lift); Log.i("Text","lift - (1/16):"+(lift - (li

40、ft/2); num+; num_y+; 3、这个没什么说的,仔细在本子上画一下就明白了,也有注释;附上全部代码package .polylinedemo;import android.content.Context;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 and

41、roid.util.AttributeSet;import android.util.Log;import android.view.View;import java.util.ArrayList;import java.util.List;import java.util.Random;/*/public class XYView03 extends View private int viewSize;/获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确) private Paint linePaint;/ 线条画笔和点画笔 private Path mPath;/ 路径对象 p

42、rivate TextPaint mTextPaint;/ 文字画笔 private List<PointF> 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轴文字坐标

43、点 private float PathX_X ; private float PathX_Y ; private float maxX;/x轴最大值 private float maxY;/Y轴最大值 private float spaceX, spaceY;/ 刻度间隔 /* * 绘制X和Y轴对应的文字 * */ int index_x = 0,1,2,3,4,5,6,7; int index_y = 0,1,2,3,4,5,6,7; public XYView03(Context context, AttributeSet attrs) super(context, attrs); /第

44、一步,初始化对象 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_FLAG); mTextPaint.setColor(Color.WHITE); /模拟数据 initData(); public XYView03(Context context) sup

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论