android自定义等级评分圆形进度条

来源:互联网 发布:windows磁盘整理 编辑:程序博客网 时间:2024/06/03 05:08

一、测试截图


二、实现原理


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 樊俊彬 * @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);}@Overrideprotected 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() {@Overridepublic void run() {curProgress++;if (curProgress == targetProgress) {timer.cancel();}postInvalidate();}};timer.schedule(timerTask, 0, 20);}@SuppressLint("DrawAllocation")@Overrideprotected 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 */@Overridepublic 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 樊俊彬 * @date 2014-10-29 * @version 1.0 */public interface onProgressChangedListener {public void progressChanged(GradeProgressBar circleProgressBar,int curProgress);}}


0 0
原创粉丝点击