自定义view折线图分析.docx

上传人:b****5 文档编号:7210364 上传时间:2023-01-21 格式:DOCX 页数:46 大小:262.53KB
下载 相关 举报
自定义view折线图分析.docx_第1页
第1页 / 共46页
自定义view折线图分析.docx_第2页
第2页 / 共46页
自定义view折线图分析.docx_第3页
第3页 / 共46页
自定义view折线图分析.docx_第4页
第4页 / 共46页
自定义view折线图分析.docx_第5页
第5页 / 共46页
点击查看更多>>
下载资源
资源描述

自定义view折线图分析.docx

《自定义view折线图分析.docx》由会员分享,可在线阅读,更多相关《自定义view折线图分析.docx(46页珍藏版)》请在冰豆网上搜索。

自定义view折线图分析.docx

自定义view折线图分析

自定义view—折线图

绘制折线图预览图

绘制这个折线图需要都需要哪些步骤?

一、如何绘制X和Y轴。

注意:

绘制线用到的是path,而绘制X和Y轴,我们需要知道三个坐标,这里我们用的是canvas.drawPath(mPath,linePaint);

1、我们来分析下,我们想知道三个坐标,那么这三个坐标是多少呢,我们该怎么计算呢?

答:

这里,我是在onSizeChanged()方法中获取到了父类控件的宽度,然后把宽度分成16份,例如,下方的上下左右四个分别如下:

lift=viewSize*(1/16f);

top=viewSize*(1/16f);

right=viewSize*(15/16f);

buttom=viewSize*(8/16f);

2、这三个坐标我们有了,那就好办了,我们根据这四个参数值,就可以知道我们上面三个坐标点的坐标,在draw()方法中,连接这三个点即可:

privatevoiddrawXY(Canvascanvas){

/*

*第三步,我们来通过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.drawPath(mPath,linePaint);

//释放画布

canvas.restore();

}

3、我们最后,在X,Y轴写个文字,那么我们需要知道X,Y这两个文字的坐标是多少?

如图:

答:

因为我们已经知道lift,right,top,buttom。

其实我们就可计算出来他们的坐标了。

其实Y轴的坐标只是向右移动一点即可(lift+num,top),x的坐标向下移动一点即可(right,top+num),其中num是你移动多少。

自己可以合理调试

privatevoiddrawXYelement(Canvascanvas){

//锁定画布

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)

**/

mTextPaint.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"

android:

background="#8B7500"

/>

编译一下效果:

4、附上全部代码

package.polylinedemo;

importandroid.content.Context;

importandroid.graphics.Canvas;

importandroid.graphics.Color;

importandroid.graphics.Paint;

importandroid.graphics.Path;

importandroid.text.TextPaint;

importandroid.util.AttributeSet;

importandroid.util.Log;

importandroid.view.View;

/**

*CreatedbyENZon2016/11/25.

*绘制自定义view折线图

*第一步:

绘制X和Y轴,那么我们需要什么准备呢?

*/

publicclassXYView01extendsView{

privateintviewSize;//获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确)

privatePaintlinePaint;//线条画笔和点画笔

privatePathmPath;//路径对象

privateTextPaintmTextPaint;//文字画笔

floatlift;

floattop;

floatright;

floatbuttom;

floatPathY_X;

floatPathY_Y;

floatPathX_X;

floatPathX_Y;

publicXYView01(Contextcontext,AttributeSetattrs){

super(context,attrs);

//第一步,初始化对象

linePaint=newPaint();

linePaint.setColor(Color.YELLOW);//线条的颜色

linePaint.setStrokeWidth(8);//线条的宽度

linePaint.setAntiAlias(true);//取消锯齿

linePaint.setStyle(Paint.Style.STROKE);//粗线

//初始化Path

mPath=newPath();

mTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG|Paint.LINEAR_TEXT_FLAG);

mTextPaint.setColor(Color.WHITE);

}

publicXYView01(Contextcontext){

super(context);

}

@Override

protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){

//在我们没学习测量控件之前强制宽高一致

super.onMeasure(widthMeasureSpec,widthMeasureSpec);

}

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

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

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

//锁定画布

canvas.save();

//定义一个绘制X,Y轴的方法

drawXY(canvas);

//绘制X和Y轴上的提示文字

drawXYelement(canvas);

}

privatevoiddrawXY(Canvascanvas){

/*

*第三步,我们来通过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.drawPath(mPath,linePaint);

//释放画布

canvas.restore();

}

privatevoiddrawXYelement(Canvascanvas){

//锁定画布

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)

**/

mTextPaint.setTextAlign(Paint.Align.RIGHT);//右对齐

canvas.drawText("X",right,buttom+50,mTextPaint);

//释放画布

canvas.restore();

}

}

1、我们绘制X和Y轴区域的子网格,我们需要知道他们范围?

Y轴上的最大范围=(buttom-top);

X轴的最大范围=(right-lift);

2、在这个范围我们需要分为多少个端即有几个数据?

每一段间距事是多少?

//假如我们有八条数据

intcount=pointFs.size();

//计算横纵坐标刻度间隔

spaceY=(buttom-top)/count;

spaceX=(right-lift)/count;

3、最大值和最小值是多少?

//计算横轴数据最大值

maxX=0;

for(inti=0;i

if(maxX

maxX=pointFs.get(i).x;//X轴最大坐标

}

}

Log.i("Text","maxX:

--"+maxX);

//计算横轴最近的能被count整除的值

intremainderX=((int)maxX)%divisor;

maxX=remainderX==0?

((int)maxX):

divisor-remainderX+((int)maxX);

//计算纵轴数据最大值

maxY=0;

for(inti=0;i

if(maxY

maxY=pointFs.get(i).y;

}

}

Log.i("Text","maxY:

--"+maxY);

//计算纵轴最近的能被count整除的值

intremainderY=((int)maxY)%divisor;

Log.i("Text","remainderY:

--"+remainderY);

4、既然我们已经知道了最大值和最小值,也知道了间距,那么我么开始绘制,通过for循环来绘制Y轴,每绘制每一个Y轴的点,都会把X轴与之相交的点全部绘制。

(自己可以在本子上画画图就容易理解了)例如下图

//锁定画布并设置画布透明度为75%

intsc=canvas.saveLayerAlpha(0,0,canvas.getWidth(),canvas.getHeight(),75,Canvas.ALL_SAVE_FLAG);

//绘制横纵线段

for(floaty=buttom-spaceY;y>top;y-=spaceY){

Log.i("Text","y"+y);

for(floatx=lift;x

Log.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;

importandroid.content.Context;

importandroid.graphics.Canvas;

importandroid.graphics.Color;

importandroid.graphics.Paint;

importandroid.graphics.Path;

importandroid.graphics.PointF;

importandroid.text.TextPaint;

importandroid.util.AttributeSet;

importandroid.util.Log;

importandroid.view.View;

importjava.util.ArrayList;

importjava.util.List;

importjava.util.Random;

/**

*CreatedbyENZon2016/11/25.

*绘制自定义view折线图

*第一步:

绘制X和Y轴,那么我们需要什么准备呢?

*/

publicclassXYView02extendsView{

privateintviewSize;//获取空间的尺寸,也就是我们布局的尺寸大小(不知道理解的是否正确)

privatePaintlinePaint;//线条画笔和点画笔

privatePathmPath;//路径对象

privateTextPaintmTextPaint;//文字画笔

privateListpointFs=newArrayList<>();//数据列表

privatefloat[]rulerX,rulerY;//xy轴向刻度

//上下左右坐标点

privatefloatlift;

privatefloattop;

privatefloatright;

privatefloatbuttom;

//Y轴文字坐标点

privatefloatPathY_X;

privatefloatPathY_Y;

//X轴文字坐标点

privatefloatPathX_X;

privatefloatPathX_Y;

privatefloatmaxX;//x轴最大值

privatefloatmaxY;//Y轴最大值

privatefloatspaceX,spaceY;//刻度间隔

publicXYView02(Contextcontext,AttributeSetattrs){

super(context,attrs);

//第一步,初始化对象

linePaint=newPaint();

linePaint.setColor(Color.YELLOW);//线条的颜色

linePaint.setStrokeWidth(8);//线条的宽度

linePaint.setAntiAlias(true);//取消锯齿

linePaint.setStyle(Paint.Style.STROKE);//粗线

//初始化Path

mPath=newPath();

mTextPaint=newTextPaint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG|Paint.LINEAR_TEXT_FLAG);

mTextPaint.setColor(Color.WHITE);

//模拟数据

initData();

}

publicXYView02(Contextcontext){

super(context);

}

@Override

protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){

//在我们没学习测量控件之前强制宽高一致

super.onMeasure(widthMeasureSpec,widthMeasureSpec);

}

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

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);

//下面是绘制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;

}

@Override

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

//锁定画布

canvas.save();

//定义一个绘制X,Y轴的方法

drawXY(canvas);

//绘制X和Y轴上的提示文字

drawXYelement(canvas);

}

privatevoidinitData(){

Randomrandom=newRandom();

pointFs=newArrayList();

for(inti=0;i<8;i++){

PointFpointF=newPointF();

pointF.x=(float)(random.nextInt(100)*i);

pointF.y=(float)(random.nextInt(100)*i);

pointFs.add(pointF);

}

}

privatevoiddrawXY(Canvascanvas){

/*

*第三步,我们来通过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.drawPath(mPath,linePaint);

//----------------------------我们在这里添加一个绘制网格的方法----------------------------------------

drawLines(canvas);

//释放画布

canvas.restore();

}

privatevoiddrawLines(Canvascanvas){

//重置线条画笔,因为是细线,所有我这里设置了2。

linePaint.setStrokeWidth

(2);

//假如我们有八条数据

intcount=pointFs.size();

//计算横纵坐标刻度间隔

spaceY=(buttom-top)/count;

spaceX=(right-lift)/count;

Log.i("Text","spaceY:

--"+spaceY);

Log.i("Text","spaceX:

--"+spaceX);

//计算除数的值为数据长度减一,8个数据,7条线。

intdivisor=count-1;

Log.i("Text","divisor:

--"+divisor);

//计算横轴数据最大值

maxX=0;

for(inti=0;i

if(maxX

maxX=pointFs.get(i).x;//X轴最大坐标

}

}

Log.i("Text","maxX:

--"+maxX);

//计算横轴最近的能被count整除的值

intremainderX=((int)maxX)%divisor;

maxX=remainderX==0?

((int)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 研究生入学考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1