android 图标控件的实现(二)
来源:互联网 发布:矩阵的微分运算法则 编辑:程序博客网 时间:2024/06/16 11:15
在这篇博客中,将实现混合柱状图
在上一篇博客中讲到过,所有的图表类都只要重载
abstract protected void startContent(Canvas canvas);//绘制图表内容
abstract protected void drawXaxis(Canvas canvas);//绘制X轴
abstract protected void drawYaxis(Canvas canvas);//绘制Y轴
接下来就看看柱状图的这三个方法的具体实现
@Override public void drawXaxis(Canvas canvas) { XaxisData xaxisData=dataManager.getxData();//从管理器中取出描述X轴的实体类 int width=canvas.getWidth(); Paint paint=getPaint(xaxisData.getLineWidth(),xaxisData.getLineColor()); canvas.drawLine(originPoint.x,originPoint.y,width,originPoint.y,paint);//从原点开始绘制一条直线作为X轴 Paint textpaint=getPaint(3,xaxisData.getLineColor()); textpaint.setTextSize(xaxisData.getTextsize()); List<Integer> xvaluesRelaticeX=getXvaluesRelativeX(xaxisData,canvas,textpaint);//取得每个柱状图中心点的X坐标 //接下来是绘制每个柱状图在X轴上的描述,就是“1月”,“2月”。。。那些文字描述 Paint rectPaint=new Paint(); rectPaint.setStrokeJoin(Paint.Join.ROUND); rectPaint.setTextSize(xaxisData.getTextsize()); for(int i=0;i<xvaluesRelaticeX.size();i++){ //先绘制一个圆角矩形,再绘制文字 textpaint.setColor(xaxisData.getXdataList().get(i).getColor()); rectPaint.setColor(xaxisData.getXdataList().get(i).getBackgroundColor()); // 矩形两边留出10,作为矩形的padding int left=xvaluesRelaticeX.get(i)-10; //头部偏移20是矩形和X轴之间留出空隙 int top=originPoint.y+20; int right= (int) (xvaluesRelaticeX.get(i)+textpaint.measureText(xaxisData.getXdataList().get(i).getText())+10); int bottom=top+xaxisData.getTextsize()+15; canvas.drawRoundRect(new RectF(left,top,right,bottom),10,10,rectPaint); //文字居中Y坐标计算参考http://blog.csdn.net/doctorzhong/article/details/53079511 int centerY= (int) ((top+bottom)/2-(textpaint.ascent()+textpaint.descent())/2); canvas.drawText(xaxisData.getXdataList().get(i).getText(),xvaluesRelaticeX.get(i),centerY,textpaint); } }
Y轴的绘制函数
@Override public void drawYaxis(Canvas canvas) { int rangNum=dataManager.getRangeNum(); //获取Y轴要分成几段 int maxValue=dataManager.getMaxValues(); //Y轴能表示的最大数据 int yaxisLength=getYaxisLength(); //Y轴的长度 Paint yaxisLinePait=getPaint(dataManager.getYaxisLineWidth(),dataManager.getYaxisLineColor()); canvas.drawLine(originPoint.x,originPoint.y,originPoint.x,originPoint.y-yaxisLength-30,yaxisLinePait);//绘制Y轴 Paint paint=getPaint(20, Color.GRAY); int rangeHeight=yaxisLength/rangNum; //计算Y轴分段后每一段的高度 int rangeValues=maxValue/rangNum; //计算每一段表示的数值大小 yaxisLinePait.setTextSize(dataManager.getYaxisTextsize()); yaxisLinePait.setColor(dataManager.getYaxisTextColor()); int xaxisLength=getXaxisLength(canvas); Paint xuxianPaint=new Paint();//绘制虚线的画笔 xuxianPaint.setColor(Color.GRAY); xuxianPaint.setStyle(Paint.Style.STROKE);//一定要设置这个属性,不然绘制不出虚线 for(int i=0;i<=rangNum;i++){ int yvalues=i*rangeValues; int yaxis=i*rangeHeight; int textwidth= (int) yaxisLinePait.measureText(yvalues+""); int x=originPoint.x-textwidth-10; int y=originPoint.y-yaxis; canvas.drawText(yvalues+"",x,y,yaxisLinePait); if(i!=0){ Path path = new Path(); path.moveTo(originPoint.x, y); path.lineTo(originPoint.x+xaxisLength,y); PathEffect effects = new DashPathEffect(new float[]{5,5},5); xuxianPaint.setPathEffect(effects); canvas.drawPath(path, xuxianPaint); } } }
最后是绘制图表的内容,就是那些柱状矩形,提示的泡泡
@Override public void startContent(Canvas canvas) { allRectangel.clear(); List<YaxisData> ydataSet=dataManager.getyDataSet();//获取Y轴数据集合 List<Integer> xrelativeValue=getXvaluesRelativeCenterX(dataManager.getxData(),canvas);//获取每个柱状图中心点的坐标 for(int i=0;i<ydataSet.size();i++){ YaxisData yaxisData=ydataSet.get(i); List<Integer> yrelativeValus=getYvaluesRelativeHeight(ydataSet.get(i)); //获取某个种类每个Y轴坐标对应的高度 Paint rectPaint=getPaint(5,yaxisData.getColor()); for(int j=0;j<xrelativeValue.size();j++){ int x=xrelativeValue.get(j); int y=yrelativeValus.get(j); int left=x-rectangleWidth/2; int top=y; int right=x+rectangleWidth/2; int bottom=originPoint.y; Rect r=new Rect(left,top,right,bottom); canvas.drawRect(r,rectPaint); if(i==0){ allRectangel.add(r);//把每个最高的矩形存起来,后面有大作用,我们公司的业务定好了第一层数据就是最大的,所以取i==0时的矩形就行 } } } }
到这里这个柱状图就绘制完了,还差一步,点击某个柱状图的时候,矩形顶部出现该柱状图详情数据的泡泡
先看看触摸事件这里的处理
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: selectValues=drawUtil.getInformationByEventMotion(event);//获取触摸点的信息,selectValues封装了摸出到的矩形位置,该矩形的顶部坐标等信息,一会再详细介绍这个函数,如果触摸到矩形的话,selectValues就不为null,然后就是更新数据了,重新绘制View if(selectValues!=null){ XaxisData xaxisData=chartDataManager.getxData(); int size=xaxisData.getXdataList().size(); for(int i=0;i<size;i++){ chartDataManager.getxData().getXdataList().get(i).setColor(Color.BLACK); chartDataManager.getxData().getXdataList().get(i).setBackgroundColor(Color.WHITE); } chartDataManager.getxData().getXdataList().get(selectValues.getPosition()).setColor(Color.WHITE); chartDataManager.getxData().getXdataList().get(selectValues.getPosition()).setBackgroundColor(Color.GREEN); invalidate(); } break; } return false; }
这里再介绍一下getInformationByEventMotion(event)方法
public RectTouchInformation getInformationByEventMotion(MotionEvent event){ RectTouchInformation selectYvalues=new RectTouchInformation(); int position=0; boolean flag=false; //遍历上面绘制图表矩形时存起来的矩形集合,判断手指触摸的是哪个矩形 for(int i=0;i<allRectangel.size();i++){ Rect r=allRectangel.get(i); if(r.contains((int)event.getX(),(int)event.getY())){ position=i; flag=true; break; } } if(!flag){ return null; } //获取选中的每个柱状图的信息 selectYvalues.setPosition(position); int size=dataManager.getyDataSet().size(); List<YaxisData> allYaxisData=dataManager.getyDataSet(); List<Yvalues> selectYpoint=new ArrayList<>(); for(int i=0;i<size;i++){ YaxisData yaxisData=allYaxisData.get(i); Yvalues yvalues=yaxisData.getYdataList().get(position); yvalues.setDescription(yaxisData.getDescription()); selectYpoint.add(yvalues); } //把选中矩形顶部中心的坐标封装进selectValues Rect rect=allRectangel.get(position); Point point=new Point(rect.left+rect.width()/2,rect.top); selectYvalues.setRectTopLineCenter(point); selectYvalues.setSelectValues(selectYpoint); return selectYvalues; }
接下来是看看如何把泡泡绘制出来的
public void drawSelectImage(Context context,Canvas canvas, RectTouchInformation selectRectInfor){ Point point=selectRectInfor.getRectTopLineCenter(); LinearLayout layout=new LinearLayout(context); layout.setBackgroundColor(Color.WHITE); layout.setOrientation(LinearLayout.VERTICAL); int size=selectRectInfor.getSelectValues().size(); for(int i=0;i<size;i++){ Yvalues yvalues=selectRectInfor.getSelectValues().get(i); TextView textView=new TextView(context); textView.setText(yvalues.getDescription()+":"+yvalues.getValue()); LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); textView.setPadding(10,2,10,2); textView.setTextSize(10); textView.setLayoutParams(params); layout.addView(textView); } //泡泡的内容首先是把它展示在View上,然后从这个View上获取到bitmap,然后绘制这个Bitmap就行,如果还是使用绘制矩形和文字的方法来实在是太麻烦了,绘制一行一行的文字就愁死人了 Bitmap selectBitmap=convertViewToBitmap(layout); int width=selectBitmap.getWidth(); int height=selectBitmap.getHeight(); int x=point.x-width/2; int y=point.y-height-20; Paint paint=new Paint(); paint.setAntiAlias(true); paint.setDither(true); paint.setColor(dataManager.getyDataSet().get(0).getColor()); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeWidth(2); paint.setStyle(Paint.Style.STROKE); RectF rectF=new RectF(x-2,y-2,x+width+2,y+height+2); //这里是给泡泡设置偏移量,以防泡泡过长超出控件了 if(rectF.left<originPoint.x){ int offset= (int) (originPoint.x-rectF.left+30); x+=offset; rectF.left=rectF.left+offset; rectF.right=rectF.right+offset; }else if(rectF.right>canvas.getWidth()){ int offset= (int) (rectF.right-canvas.getWidth()+30); x-=offset; rectF.left=rectF.left-offset; rectF.right=rectF.right-offset; } //最后是绘制出指示箭头 canvas.drawRoundRect(rectF,10,10,paint); canvas.drawLine(point.x,point.y,point.x-10,rectF.bottom,paint); canvas.drawLine(point.x,point.y,point.x+10,rectF.bottom,paint); paint.setColor(Color.WHITE); canvas.drawLine(point.x,rectF.bottom,point.x-10,rectF.bottom,paint); canvas.drawLine(point.x,rectF.bottom,point.x+10,rectF.bottom,paint); canvas.drawBitmap(selectBitmap,x,y,new Paint()); }
阅读全文
0 0
- android 图标控件的实现(二)
- android 图标控件的实现(一)
- Android圆形头像(图标)的实现
- android 控件 带图标的按钮(ImageButton)
- Android的Tab控件(二)
- Android的GridView控件(二)
- Android的GridView控件 (二)
- android的自定义控件简单(二)
- 日期控件二的实现
- Android: 带图标的ListView实现
- android中图标重叠的实现
- 基于Android图标拖动布局的实现
- Android实现带图标的ListView
- Android实现带图标的ListView
- Android中未读信息提示图标的实现
- Android 5.0状态栏通知图标的实现
- Android 图标控件 Hellocharts使用手册
- Android定制控件:带图标的TextView和可编辑文本框(附项目源码)
- JavaMail实现发送邮件实测可用
- ionic APP上传到apple store
- 树状数组一(二)维区间修改与求和
- nginx 调测 优化
- artTemplate实现三层菜单
- android 图标控件的实现(二)
- C++---array
- Centos 6.8 安装git
- 浅谈如何成功实施项目管理
- 统计难题(字典树-HDU-1251)
- nyoj 76超级台阶
- idea中文乱码终极解决方案
- 剑指offer第一题:二维数组中的查找解题报告
- 深入理解JavaScript闭包概念