首页 > 系统 > Android > 正文

Android-自定义环形统计图

2019-11-07 23:08:25
字体:
来源:转载
供稿:网友

由于前段时间回老家处理事情,所以这篇文章拖到了今天才有时间来写,请大家谅解!

由于在群里面有同学需要环形统计图,所以抽了点时间写出来,下面为大家提供上源码,以供大家交流分析指正。 先上效果图: 环形统计图

以下贴上源码:

/** * Created by lxh on 2017/2/10. * QQ-632671653 */public class CircularStatisticsView extends View { /** * 第一圈的颜色 */ PRivate int mFirstColor = Color.BLUE; /** * 第二圈的颜色 */ private int mSecondColor = Color.RED; /** * 圈的宽度 */ private float mCircleWidth = 200; /** * 画笔 */ private Paint mPaint; /** * 当前进度 */ private int mProgress = 20; /** * 剩余文字 */ private String reminderText = "剩余"; /** * 进度文字 */ private String progressText = "已使用"; /** * 中心x坐标 */ int centreX; /** * 中心y坐标 */ int centerY; public CircularStatisticsView(Context context, AttributeSet attrs) { super(context, attrs); } public CircularStatisticsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public CircularStatisticsView(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { mPaint = new Paint(); centreX = getWidth() / 2; // 获取圆心的x坐标 centerY = getHeight() / 2; int radius = centreX/2;// 半径 mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度 mPaint.setAntiAlias(true); // 消除锯齿 mPaint.setStyle(Paint.Style.STROKE); // 设置空心 RectF oval = new RectF(centreX - radius, centerY - radius, centreX + radius, centerY + radius); // 用于定义的圆弧的形状和大小的界限 mPaint.setColor(mFirstColor); // 设置圆环的颜色 canvas.drawCircle(centreX, centerY, radius, mPaint); // 画出圆环 mPaint.setColor(mSecondColor); // 设置圆弧的颜色 canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧 //获取进度圆弧的中心点 float textX1 = (float) (centreX + (radius+mCircleWidth/2)*Math.cos(2*Math.PI*(mProgress/2-90)/360)); float textY1 = (float) (centerY + (radius+mCircleWidth/2)*Math.sin(2*Math.PI*(mProgress/2-90)/360)); Paint paint = new Paint(); paint.setStrokeWidth(2); // 设置圆环的宽度 paint.setAntiAlias(true); // 消除锯齿 paint.setColor(mSecondColor); paint.setTextSize(30); drawText(canvas,progressText+getPer(mProgress,360),textX1,textY1,paint); float textX2 = (float) (centreX + (radius+mCircleWidth/2)*Math.cos(2*Math.PI*((mProgress-360)/2-90)/360)); float textY2 = (float) (centerY + (radius+mCircleWidth/2)*Math.sin(2*Math.PI*((mProgress-360)/2-90)/360)); paint.setColor(mFirstColor); drawText(canvas,reminderText+getPer(360-mProgress,360),textX2,textY2,paint); } /** * 计算百分比 * @param now * @param total * @return */ private String getPer(int now,int total){ // 创建一个数值格式化对象 NumberFormat numberFormat = NumberFormat.getInstance(); // 设置精确到小数点后2位 numberFormat.setMaximumFractionDigits(2); String result = numberFormat.format((float) now / (float) total * 100); return result+"%"; } /** * 设置剩余进度颜色 * @param color */ public void setReminderColor(int color){ mFirstColor = color; invalidate(); } /** * 设置当前进度颜色 * @param color */ public void setProgressColor(int color){ mSecondColor = color; invalidate(); } /** * 设置剩余进度文字 * @param text */ public void setReminderText(String text){ reminderText = text; invalidate(); } /** * 设置当前进度文字 * @param text */ public void setProgressText(String text){ progressText = text; invalidate(); } /** * 设置圆环宽度 * @param width */ public void setCircleWidth(int width){ mCircleWidth = width; invalidate(); } /** * 设置当前进度 * @param total 总量 * @param now 当前进度量 */ public void setProgress(float total,float now){ mProgress = (int) ((now/total)*360); postInvalidate(); } /** * 绘制文字 * @param canvas * @param string * @param firstX * @param firstY * @param paint */ private void drawText(Canvas canvas,String string,float firstX,float firstY,Paint paint){ float endX1 = 0; float endY1 = 0; float endX2 = 0; float endY2 = 0; float textX = 0; float textY = 0; //初始点位于第四象限 if (firstX<=centreX&&firstY<=centerY){ endX1 = firstX - 50; endY1 = firstY - 50; endX2 = firstX-200; endY2 = firstY-50; textX = endX2; textY = endY2-10; } //初始点位于第三象限 if (firstX<centreX&&firstY>centerY){ endX1 = firstX - 50; endY1 = firstY + 50; endX2 = firstX - 200; endY2 = firstY + 50; textX = endX2; textY = endY2+40; } //初始点位于第一象限 if (firstX>centreX&&firstY<centerY){ endX1 = firstX + 50; endY1 = firstY - 50; endX2 = firstX + 200; endY2 = firstY - 50; textX = endX1; textY = endY2-10; } //初始点位于第二象限 if (firstX>=centreX&&firstY>=centerY){ endX1 = firstX + 50; endY1 = firstY + 50; endX2 = firstX + 200; endY2 = firstY + 50; textX = endX1; textY = endY2+40; } canvas.drawLine(firstX,firstY,endX1,endY1,paint); canvas.drawLine(endX1,endY1,endX2,endY2,paint); canvas.drawText(string,textX,textY,paint); }}

xml中直接使用:

<com.lxh.usermodule.CircularStatisticsView android:id="@+id/circularStatisticsView" android:layout_width="wrap_content" android:layout_height="wrap_content" />

在activity中初始化各项属性:

circularStatisticsView = (CircularStatisticsView) findViewById(R.id.circularStatisticsView); circularStatisticsView.setOnClickListener(this); circularStatisticsView.setReminderText("剩余"); circularStatisticsView.setProgressText("已使用"); circularStatisticsView.setProgress(15638,2546); circularStatisticsView.setReminderColor(Color.parseColor("#FF0000FF")); circularStatisticsView.setProgressColor(Color.parseColor("#FFFF0000")); circularStatisticsView.setCircleWidth(200);

源码中有详细的注解,由于时间因素,本控件还有很多需要完善的地方,希望大家自行扩展完善,感谢大家。更多技术交流请加本人QQ:632671653,微信:15123534435


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表