android自定义等级评分圆形进度条
更新时间:2020年7月16日 21:10 点击:1292
本文实例为大家分享了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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
上一篇: android自定义环形统计图动画
下一篇: Android自定义条形对比统计图
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 这篇文章主要介绍了解决echarts 一条柱状图显示两个值,类似进度条的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-20
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 本文实例讲述了jQuery实现文件上传进度条效果的代码。分享给大家供大家参考。具体如下: 运行效果截图如下:具体代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>upload</title><link rel="stylesheet...2015-11-24
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 本文实例讲述了jquery实现模拟百分比进度条渐变效果代码。分享给大家供大家参考,具体如下:这里为了便于看到加载百分比,对代码进行了处理,实际使用时并不需要这样。运行效果截图如下:在线演示地址如下:http://demo.jb51.net...2015-10-30
ant design中upload组件上传大文件,显示进度条进度的实例
这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 这篇文章主要介绍了C#实现带进度条的ListView 的相关资料,需要的朋友可以参考下...2020-06-25
- 首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
- 在网页中,经常见到进度条效果,那么这些个性的进度条组件效果是怎么实现的呢,下面脚本之家小编给大家分享Bootstrap进度条组件知识详解,感兴趣的朋友要求学习吧...2016-05-04