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

一、测试截图

c08c5fbd6f013bc84062b9125eaa4e77.png

二、实现原理

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 自定义等级评分圆形进度条,用于设备数据统计页面一键评分

* 1、初始化边界宽度、中心坐标和外环、内环半径,各种画笔。

* 2、默认最大进度为100,目标进度由用户来指定。

* 3、锁定一个内圆环为可点击区域。

* 4、点击组件时,调用start()方法启动计时器,重绘界面。

* @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 对外接口,提供当前旋转进度

* 1、

* 2、

* @author Freedoman

* @date 2014-10-29

* @version 1.0

*/

public interface onProgressChangedListener {

public void progressChanged(GradeProgressBar circleProgressBar,

int curProgress);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值