自定义view折线图.docx
- 文档编号:29682178
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:54
- 大小:262.46KB
自定义view折线图.docx
《自定义view折线图.docx》由会员分享,可在线阅读,更多相关《自定义view折线图.docx(54页珍藏版)》请在冰豆网上搜索。
自定义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;//文字画笔 privateList 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)ma
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 自定义 view 折线
![提示](https://static.bdocx.com/images/bang_tan.gif)