android评分圆形进度条 android自定义等级评分圆形进度条
Freedoman1990 人气:0一、测试截图
二、实现原理
package com.freedomanlib; import java.util.Timer; import java.util.TimerTask; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * @name GradeProgressBar * @Descripation 自定义等级评分圆形进度条,用于设备数据统计页面一键评分<br> * 1、初始化边界宽度、中心坐标和外环、内环半径,各种画笔。<br> * 2、默认最大进度为100,目标进度由用户来指定。<br> * 3、锁定一个内圆环为可点击区域。 <br> * 4、点击组件时,调用start()方法启动计时器,重绘界面。<br> * @author Freedoman * @date 2014-10-29 * @version 1.0 */ public class GradeProgressBar extends View { private static final String TAG = "CircleProgressBar"; /** * 边界宽度、中心坐标和外环、内环半径 */ private float boundsWidth; private float centerPoint; private float overRadius; private float radius; /** * 最大进度、当前进度、是否显示进度文本 */ private float maxProgress = 100; private float targetProgress; private int curProgress; /** * 几种画笔 */ private Paint overRoundPaint; private Paint roundPaint; private Paint progressRoundPaint; private Paint progressTextPaint; private Paint textPaint; /** * 可点击区域的边界 */ private float clickBoundsLow; private float clickBoundsHigh; private onProgressChangedListener listener; public GradeProgressBar(Context context) { this(context, null); } public GradeProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GradeProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.initialize(); } /** * 初始化 */ private void initialize() { curProgress = 0; int whiteColor = Color.rgb(0xF0, 0xF0, 0xF0); // 外环画笔 overRoundPaint = new Paint(); overRoundPaint.setColor(whiteColor); overRoundPaint.setStyle(Paint.Style.STROKE); overRoundPaint.setStrokeWidth(8); overRoundPaint.setAntiAlias(true); // 内环画笔 roundPaint = new Paint(); roundPaint.setColor(Color.GRAY); roundPaint.setStrokeWidth(30); roundPaint.setStyle(Paint.Style.STROKE); roundPaint.setAntiAlias(true); // 进度环画笔(除颜色外同于内环) progressRoundPaint = new Paint(); progressRoundPaint.setColor(Color.rgb(0xFF, 0x92, 0x24)); progressRoundPaint.setStrokeWidth(20); progressRoundPaint.setStyle(Paint.Style.STROKE); roundPaint.setAntiAlias(true); // 进度文本画笔 progressTextPaint = new Paint(); progressTextPaint.setColor(whiteColor); progressTextPaint.setStyle(Paint.Style.STROKE); progressTextPaint.setStrokeWidth(0); progressTextPaint.setTextSize(80); progressTextPaint.setTypeface(Typeface.DEFAULT_BOLD); // 文本画笔 textPaint = new Paint(); textPaint.setColor(whiteColor); textPaint.setStyle(Paint.Style.STROKE); textPaint.setStrokeWidth(0); textPaint.setTextSize(40); textPaint.setTypeface(Typeface.DEFAULT_BOLD); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 取当前布局的最短边作为边框的长度 float width = getWidth(); float heigh = getHeight(); boundsWidth = width <= heigh ? width : heigh; // 中心点 centerPoint = boundsWidth / 2; // 外环半径 overRadius = centerPoint - 20; // 内环半径 radius = overRadius - 25; // 内环所在区域(正方形)锁定为可点击区域 clickBoundsLow = centerPoint - radius; clickBoundsHigh = centerPoint + radius; } /** * 启动进度动画 */ public void start() { curProgress = 0; if (targetProgress == 0) { targetProgress = 66; } final Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { curProgress++; if (curProgress == targetProgress) { timer.cancel(); } postInvalidate(); } }; timer.schedule(timerTask, 0, 20); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 外环 canvas.drawCircle(centerPoint, centerPoint, overRadius, overRoundPaint); // 内环 canvas.drawCircle(centerPoint, centerPoint, radius, roundPaint); // 进度环 RectF oval = new RectF(centerPoint - radius, centerPoint - radius, centerPoint + radius, centerPoint + radius); float curArc = 360 * curProgress / maxProgress; canvas.drawArc(oval, 0, curArc, false, progressRoundPaint); // 环中心进度文本 int curPercent = (int) ((curProgress / maxProgress) * 100); float textWidth = progressTextPaint.measureText(curPercent + "%"); canvas.drawText(curPercent + "%", centerPoint - textWidth / 2, centerPoint, progressTextPaint); if (curPercent == 0) { // 暂未评级 float w = textPaint.measureText("暂未评级"); canvas.drawText("暂未评级", centerPoint - w / 2, centerPoint + 40, textPaint); } else if (curPercent < targetProgress) { // 评级中... float w = textPaint.measureText("评级中..."); canvas.drawText("评级中...", centerPoint - w / 2, centerPoint + 40, textPaint); } else if (curPercent == targetProgress) { // 评级完成 float w = textPaint.measureText("评级完成"); canvas.drawText("评级完成", centerPoint - w / 2, centerPoint + 40, textPaint); } // 对外传递数据 if (listener != null) { listener.progressChanged(GradeProgressBar.this, curProgress); } } public synchronized float getMaxProgress() { return maxProgress; } /** * 设置进度的最大值 * * @param max */ public synchronized void setMaxProgress(float max) { if (max < 0) { throw new IllegalArgumentException("max not less than 0"); } this.maxProgress = max; } /** * 获取进度.需要同步 * * @return */ public synchronized float getProgress() { return targetProgress; } /** * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 刷新界面调用postInvalidate()能在非UI线程刷新 * * @param progress */ public synchronized void setProgress(float progress) { if (progress < 0) { throw new IllegalArgumentException("progress not less than 0"); } if (progress > maxProgress) { progress = maxProgress; } if (progress <= maxProgress) { this.targetProgress = progress; } } public void setOnProgressChangedListener(onProgressChangedListener listener) { if (listener == null) { this.listener = listener; } } /** * 点击评分区域,进行评分 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); if (x > clickBoundsLow && x < clickBoundsHigh && y > clickBoundsLow && y < clickBoundsHigh) { start(); } return super.onTouchEvent(event); } /** * @name onProgressChangedListener * @Descripation 对外接口,提供当前旋转进度<br> * 1、<br> * 2、<br> * @author Freedoman * @date 2014-10-29 * @version 1.0 */ public interface onProgressChangedListener { public void progressChanged(GradeProgressBar circleProgressBar, int curProgress); } }
加载全部内容