Android 自定义View实现芝麻分曲线图效果

Android 自定义View实现芝麻分曲线图效果,第1张

概述1.简介其实这个效果几天之前就写了,但是一直没有更新博客,本来想着把芝麻分雷达图也做好再发博客的,然后今天看到鸿洋的微信公众号有朋友发了芝麻分的雷达图,所以就算了,算是一个互补吧。平时文章也写的比较少,

1.简介

其实这个效果几天之前就写了,但是一直没有更新博客,本来想着把芝麻分雷达图也做好再发博客的,然后今天看到鸿洋的微信公众号有朋友发了芝麻分的雷达图,所以就算了,算是一个互补吧。平时文章也写的比较少,所以可能有点杂乱,有什么需要改进的地方欢迎给出建议,不胜感激。

效果图:

2.步骤:

初始化VIEw的属性
初始化画笔
绘制代表最高分和最低分的两根虚线
绘制文字
绘制代表月份的属性
绘制芝麻分折线
绘制代表芝麻分的圆点
绘制选中分数的悬浮文字以及背景
处理点击事件

3.编码:

初始化VIEw属性

/*** 初始化布局配置** @param context* @param attrs*/private voID initConfig(Context context,AttributeSet attrs){TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.scoreTrend);maxscore=a.getInt(R.styleable.scoreTrend_max_score,700);minscore=a.getInt(R.styleable.scoreTrend_min_score,650);brokenlinecolor=a.getcolor(R.styleable.scoreTrend_broken_line_color,brokenlinecolor);a.recycle();}

初始化画笔:

private voID init(){brokenPath = new Path();brokenPaint = new Paint();brokenPaint.setAntiAlias(true);brokenPaint.setStyle(Paint.Style.stroke);brokenPaint.setstrokeWIDth(diptopx(brokenlineWith));brokenPaint.setstrokeCap(Paint.Cap.ROUND);straightPaint = new Paint();straightPaint.setAntiAlias(true);straightPaint.setStyle(Paint.Style.stroke);straightPaint.setstrokeWIDth(brokenlineWith);straightPaint.setcolor((straightlinecolor));straightPaint.setstrokeCap(Paint.Cap.ROUND);dottedPaint = new Paint();dottedPaint.setAntiAlias(true);dottedPaint.setStyle(Paint.Style.stroke);dottedPaint.setstrokeWIDth(brokenlineWith);dottedPaint.setcolor((straightlinecolor));dottedPaint.setstrokeCap(Paint.Cap.ROUND);textPaint = new Paint();textPaint.setAntiAlias(true);textPaint.setTextAlign(Paint.Align.CENTER);textPaint.setStyle(Paint.Style.FILL);textPaint.setcolor((textnormalcolor));textPaint.setTextSize(diptopx(15));}

绘制代表最高分和最低分虚线

//绘制虚线private voID drawDottedline(Canvas canvas,float startX,float startY,float stopX,float stopY){dottedPaint.setPathEffect(new DashPathEffect(new float[]{20,10},4));dottedPaint.setstrokeWIDth(1);// 实例化路径Path mPath = new Path();mPath.reset();// 定义路径的起点mPath.moveto(startX,startY);mPath.lineto(stopX,stopY);canvas.drawPath(mPath,dottedPaint);}

绘制文本

//绘制文本private voID drawText(Canvas canvas){textPaint.setTextSize(diptopx(12));textPaint.setcolor(textnormalcolor);canvas.drawText(String.valueOf(maxscore),vIEwWith * 0.1f - diptopx(10),vIEwHeight * 0.15f + textSize * 0.25f,textPaint);canvas.drawText(String.valueOf(minscore),vIEwHeight * 0.4f + textSize * 0.25f,textPaint);textPaint.setcolor(0xff7c7c7c);float newWith = vIEwWith - (vIEwWith * 0.15f) * 2;//分隔线距离最左边和最右边的距离是0.15倍的vIEwWithfloat coordinateX;//分隔线X坐标textPaint.setTextSize(diptopx(12));textPaint.setStyle(Paint.Style.FILL);textPaint.setcolor(textnormalcolor);textSize = (int) textPaint.getTextSize();for(int i = 0; i < monthText.length; i++){coordinateX = newWith * ((float) (i) / (monthCount - 1)) + (vIEwWith * 0.15f);if(i == selectMonth - 1){textPaint.setStyle(Paint.Style.stroke);textPaint.setcolor(brokenlinecolor);RectF r2 = new RectF();r2.left = coordinateX - textSize - diptopx(4);r2.top = vIEwHeight * 0.7f + diptopx(4) + textSize / 2;r2.right = coordinateX + textSize + diptopx(4);r2.bottom = vIEwHeight * 0.7f + diptopx(4) + textSize + diptopx(8);canvas.drawRoundRect(r2,10,textPaint);}//绘制月份canvas.drawText(monthText[i],coordinateX,vIEwHeight * 0.7f + diptopx(4) + textSize + diptopx(5),textPaint);textPaint.setcolor(textnormalcolor);}}

绘制代表月份的属性

//绘制月份的直线(包括刻度)private voID drawMonthline(Canvas canvas){straightPaint.setstrokeWIDth(diptopx(1));canvas.drawline(0,vIEwHeight * 0.7f,vIEwWith,straightPaint);float newWith = vIEwWith - (vIEwWith * 0.15f) * 2;//分隔线距离最左边和最右边的距离是0.15倍的vIEwWithfloat coordinateX;//分隔线X坐标for(int i = 0; i < monthCount; i++){coordinateX = newWith * ((float) (i) / (monthCount - 1)) + (vIEwWith * 0.15f);canvas.drawline(coordinateX,vIEwHeight * 0.7f + diptopx(4),straightPaint);}}

绘制芝麻分折线

//绘制折线private voID drawbrokenline(Canvas canvas){brokenPath.reset();brokenPaint.setcolor(brokenlinecolor);brokenPaint.setStyle(Paint.Style.stroke);if(score.length == 0){return;}Log.v("scoreTrend","drawbrokenline: " + scorePoints.get(0));brokenPath.moveto(scorePoints.get(0).x,scorePoints.get(0).y);for(int i = 0; i < scorePoints.size(); i++){brokenPath.lineto(scorePoints.get(i).x,scorePoints.get(i).y);}canvas.drawPath(brokenPath,brokenPaint);}

绘制代表芝麻分的圆点

//绘制折线穿过的点private voID drawPoint(Canvas canvas){if(scorePoints == null){return;}brokenPaint.setstrokeWIDth(diptopx(1));for(int i = 0; i < scorePoints.size(); i++){brokenPaint.setcolor(brokenlinecolor);brokenPaint.setStyle(Paint.Style.stroke);canvas.drawCircle(scorePoints.get(i).x,scorePoints.get(i).y,diptopx(3),brokenPaint);brokenPaint.setcolor(color.WHITE);brokenPaint.setStyle(Paint.Style.FILL);if(i == selectMonth - 1){brokenPaint.setcolor(0xffd0f3f2);canvas.drawCircle(scorePoints.get(i).x,diptopx(8f),brokenPaint);brokenPaint.setcolor(0xff81dddb);canvas.drawCircle(scorePoints.get(i).x,diptopx(5f),brokenPaint);//绘制浮动文本背景框drawfloatTextBackground(canvas,scorePoints.get(i).x,scorePoints.get(i).y - diptopx(8f));textPaint.setcolor(0xffffffff);//绘制浮动文字canvas.drawText(String.valueOf(score[i]),scorePoints.get(i).y - diptopx(5f) - textSize,textPaint);}brokenPaint.setcolor(0xffffffff);canvas.drawCircle(scorePoints.get(i).x,diptopx(1.5f),brokenPaint);brokenPaint.setStyle(Paint.Style.stroke);brokenPaint.setcolor(brokenlinecolor);canvas.drawCircle(scorePoints.get(i).x,diptopx(2.5f),brokenPaint);}}

绘制选中分数的悬浮文字以及背景

//绘制显示浮动文字的背景private voID drawfloatTextBackground(Canvas canvas,int x,int y){brokenPath.reset();brokenPaint.setcolor(brokenlinecolor);brokenPaint.setStyle(Paint.Style.FILL);//P1Point point = new Point(x,y);brokenPath.moveto(point.x,point.y);//P2point.x = point.x + diptopx(5);point.y = point.y - diptopx(5);brokenPath.lineto(point.x,point.y);//P3point.x = point.x + diptopx(12);brokenPath.lineto(point.x,point.y);//P4point.y = point.y - diptopx(17);brokenPath.lineto(point.x,point.y);//P5point.x = point.x - diptopx(34);brokenPath.lineto(point.x,point.y);//P6point.y = point.y + diptopx(17);brokenPath.lineto(point.x,point.y);//P7point.x = point.x + diptopx(12);brokenPath.lineto(point.x,point.y);//最后一个点连接到第一个点brokenPath.lineto(x,y);canvas.drawPath(brokenPath,brokenPaint);}

处理点击事件

@OverrIDepublic boolean ontouchEvent(MotionEvent event){this.getParent().requestdisallowIntercepttouchEvent(true);//一旦底层VIEw收到touch的action后调用这个方法那么父层VIEw就不会再调用onIntercepttouchEvent了,也无法截获以后的actionswitch(event.getAction()){case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:onActionUpEvent(event);this.getParent().requestdisallowIntercepttouchEvent(false);break;case MotionEvent.ACTION_CANCEL:this.getParent().requestdisallowIntercepttouchEvent(false);break;}return true;}private voID onActionUpEvent(MotionEvent event){boolean isValIDtouch = valIDatetouch(event.getX(),event.getY());if(isValIDtouch){invalIDate();}}//是否是有效的触摸范围private boolean valIDatetouch(float x,float y){//曲线触摸区域for(int i = 0; i < scorePoints.size(); i++){// diptopx(8)乘以2为了适当增大触摸面积if(x > (scorePoints.get(i).x - diptopx(8) * 2) && x < (scorePoints.get(i).x + diptopx(8) * 2)){if(y > (scorePoints.get(i).y - diptopx(8) * 2) && y < (scorePoints.get(i).y + diptopx(8) * 2)){selectMonth = i + 1;return true;}}}//月份触摸区域//计算每个月份X坐标的中心点float monthtouchY = vIEwHeight * 0.7f - diptopx(3);//减去diptopx(3)增大触摸面积float newWith = vIEwWith - (vIEwWith * 0.15f) * 2;//分隔线距离最左边和最右边的距离是0.15倍的vIEwWithfloat valIDtouchX[] = new float[monthText.length];for(int i = 0; i < monthText.length; i++){valIDtouchX[i] = newWith * ((float) (i) / (monthCount - 1)) + (vIEwWith * 0.15f);}if(y > monthtouchY){for(int i = 0; i < valIDtouchX.length; i++){Log.v("scoreTrend","valIDatetouch: valIDtouchX:" + valIDtouchX[i]);if(x < valIDtouchX[i] + diptopx(8) && x > valIDtouchX[i] - diptopx(8)){Log.v("scoreTrend","valIDatetouch: " + (i + 1));selectMonth = i + 1;return true;}}}return false;}

获取控件的宽高

@OverrIDeprotected voID onSizeChanged(int w,int h,int olDW,int oldh){super.onSizeChanged(w,h,olDW,oldh);vIEwWith = w;vIEwHeight = h;initData();}

4.总结

还有一些比较不够完善的地方需要处理,比如说可以通过XML调节的属性太少了。平时写的东西还是太少了,希望以后多总结完善写作功底吧。需要的属性后面需要再完善吧

GitHub地址:https://github.com/FelixLee0527/ZhiMaScoreCurve

以上所述是小编给大家介绍的AndroID 自定义view实现芝麻分曲线图效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android 自定义View实现芝麻分曲线图效果全部内容,希望文章能够帮你解决Android 自定义View实现芝麻分曲线图效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1147699.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存