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

本文实例为大家分享了android评分圆形进度条的具体代码,供大家参考,具体内容如下

一、测试截图

二、实现原理

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);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 自定义圆形带刻度渐变色的进度条样式实例代码

    效果图 一.绘制圆环 圆环故名思意,第一个首先绘制是圆环 1:圆环绘制函数 圆环API public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 参数说明 oval:圆弧所在的椭圆对象. startAngle:圆弧的起始角度. sweepAngle:圆弧的角度. useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不

  • Android实现渐变圆环、圆形进度条效果

    最近做了一个功能,里面涉及到了渐变圆形的需求.就是一个颜色可以渐变的圆环,最后实现的效果如下图: 左图是带渐变效果,右图是不带渐变效果.原理还是绘图,Canvas可以绘制的对象有:弧线(arcs).填充颜色(argb和color). Bitmap.圆(circle和oval).点(point).线(line).矩形(Rect).图片(Picture).圆角矩形 (RoundRect).文本(text).顶点(Vertices).路径(path).通过组合这些对象我们可以画出一些简单有趣的界面出来

  • Android自定义圆形倒计时进度条

    效果预览 源代码传送门:https://github.com/yanzhenjie/CircleTextProgressbar 实现与原理 这个文字圆形的进度条我们在很多APP中看到过,比如APP欢迎页倒计时,下载文件倒计时等. 分析下原理,可能有的同学一看到这个自定义View就慌了,这个是不是要继承View啊,是不是要绘制啊之类的,答案是:是的.但是我们也不要担心,实现这个效果实在是so easy.下面就跟我一起来看看核心分析和代码吧. 原理分析 首先我们观察上图,需要几个部分组成: 1. 外

  • Android编程之ProgressBar圆形进度条颜色设置方法

    本文实例讲述了Android ProgressBar圆形进度条颜色设置方法.分享给大家供大家参考,具体如下: 你是不是还在为设置进度条的颜色而烦恼呢--别着急,且看如下如何解决. ProgressBar分圆形进度条和水平进度条 我这里就分享下如何设置圆形进度条的颜色吧,希望对大家会有帮助. 源码如下: 布局文件代码: <ProgressBar android:id="@+id/progressbar" android:layout_width="wrap_content

  • Android三种方式实现ProgressBar自定义圆形进度条

    进度条样式在项目中经常可以见到,下面小编给大家分享Android三种方式实现ProgressBar自定义圆形进度条. Android进度条有4种风格可以使用. 默认值是progressBarStyle. 设置成progressBarStyleSmall后,图标变小. 设置成progressBarStyleLarge后,图标变大 设置成progressBarStyleHorizontal后,变成横向长方形. 自定义圆形进度条ProgressBar的一般有三种方式: 一.通过动画实现 定义res/a

  • Android带进度的圆形进度条

    我们还是用一个小例子来看看自定义View和自定义属性的使用,带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧 从上面可以看出,我们可以自定义圆环的颜色,圆环进度的颜色,是否显示进度的百分比,进度百分比的颜色,以及进度是实心还是空心等等,这样子是不是很多元化很方便呢?接下来我们就来教大家怎么来定义 1.在values下面新建一个attrs.xml,现在里面定义我们的属性,不同的属性对应不同的format,接下来我贴上我在自定义这个进度条所用到的属性 <?xml version="

  • android自定义进度条渐变圆形

    在安全卫生上,经常看到有圆形的进度条在转动,效果非常好看,于是就尝试去实现一下,具体实现过程不多说了,直接上效果图,先炫耀下. 效果图: 分析:比较常见于扫描结果.进度条等场景 利用canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)绘制圆弧 Paint的一些属性定义粗细.颜色.样式等 LinearGradient实现颜色的线型渐变 同样的道理,可以画出长条进度

  • Android studio圆形进度条 百分数跟随变化

    本文实例为大家分享了Android studio圆形进度条展示的具体代码,供大家参考,具体内容如下 MainActivity import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity impl

  • 自定义Android圆形进度条(附源码)

    本文实例讲述了Android自定义圆形进度条,分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 自定义的View: import com.example.circlepregress.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import andr

  • Android使用Canvas绘制圆形进度条效果

    前言 Android自定义控件经常会用到Canvas绘制2D图形,在优化自己自定义控件技能之前,必须熟练掌握Canvas绘图机制.本文从以下三个方面对Canvas绘图机制进行讲解: 画布Canvas 画笔Paint 示例圆形进度条 画布Canvas 首先,来看一下Android官网对Canvas类的定义: The Canvas class holds the "draw" calls.To draw something, you need 4 basic components: A B

随机推荐