背景

Android花样loading进度条系列文章主要讲解如何自定义所需的进度条,包括水平、圆形、环形、圆弧形、不规则形状等。
本篇我们对配文字环形进度条稍加变换,将圆环颜色改为渐变色的形式,使得进度条更具有色彩性,其他内容同上一篇Android花样loading进度条(三)-配文字环形进度条,主要是使用Canvas绘制圆和圆弧、绘制文字。

效果

先上图看效果,这里有4个进度条,样式上有微妙区别,基本都属于一个类别的进度条了。

4个进度条基本上分为3类:

  1. 带文字的渐变色进度条;
  2. 不带文字的渐变色进度条;
  3. 带自定义字体的渐变色进度条

我们以第1种作为基本示例来讲解,需要准备的知识点有:

  • 自定义控件的坐标轴;
  • Canvas圆环、圆弧绘制方法;
  • Paint画笔着色器的使用方法;
  • Canvas文字绘制方法;
  • 自定义属性;
  • Handler消息处理机制。

其中除了Paint画笔着色器的使用方法没有说,其他都在上一篇 Android花样loading进度条(三)-配文字环形进度条一文中有讲解过。

Paint的着色器

Canvas画板中的内容依靠Paint画笔来绘制,因为在绘制渐变色圆环时需要对画笔设置渐变色效果,我们看到Paint画笔有一个方法:

android.graphics.Paint#setShader(Shader shader)

Android中提供了以下几种Shader :

  • LinearGradient:线性渐变效果,比较适合在矩形、线条形状的图形添加渐变效果;
  • SweepGradient:梯度渐变,也称之为扫描式渐变,比较适合做圆、圆环上的渐变效果;
  • RadialGradient:径向渐变,类似于中心发散效果,比较适合做靶环效果。

想要获取更多的渐变效果及详情资料,可以参考:https://www.cnblogs.com/tianzhijiexian/p/4298660.html,或百度学习。

自定义属性

渐变色的环形进度条控件一般定义的属性有:

  • 圆环的颜色;
  • 圆环的宽度;
  • 圆环上的进度颜色;
  • 圆环上的进度宽度;
  • 文字大小;
  • 文字颜色;
  • 百分比大小;
  • 渐变色色值等。

为此,我们定义attrs.xml配置文件的内容为:

<!--渐变色环形进度-->
<declare-styleable name="GradientRoundProgress"><!--圆环颜色--><attr name="grp_roundColor" format="color" /><!--圆环的宽度--><attr name="grp_roundWidth" format="dimension" /><!--圆环上的进度颜色--><attr name="grp_progressColor" format="color" /><!--圆环上的进度宽度--><attr name="grp_progressWidth" format="dimension" /><!--文字内容--><attr name="grp_text" format="string" /><!--文字指示颜色--><attr name="grp_textColor" format="color" /><!--文字指示字体大小--><attr name="grp_textSize" format="dimension" /><!--数字指示字体大小--><attr name="grp_numSize" format="dimension" /><!--进度值的最大值,一般为100--><attr name="grp_max" format="integer" /><!--是否显示文字指示内容--><attr name="grp_textShow" format="boolean" /><!--开始角度,指定进度初始点的绘制位置--><attr name="grp_startAngle" format="integer" /><!--是否使用自定义字体--><attr name="grp_userCustomFont" format="boolean" /><!--渐变色起始色--><attr name="grp_startColor" format="color" /><!--渐变色中间色--><attr name="grp_midColor" format="color" /><!--渐变色起始色--><attr name="grp_endColor" format="color" />
</declare-styleable>

有了属性定义后,我们在绘制的时候结合这些属性就可以按设置值绘制了。

基本图形绘制

除渐变色环形进度条的绘制外,其他绘制方法均可参考上一篇 Android花样loading进度条(三)-配文字环形进度条中的讲解,或自己做一些修改。

渐变色圆环绘制

与之前的进度条不同,渐变色圆环的进度条需要在背景环上绘制带有渐变色效果的前景环。
1、绘制背景圆环(底色)
这个和上一篇文章一样,利用paint绘制指定背景色和粗细的圆环。

// step1 画最外层的大圆环
paint.setStrokeWidth(roundWidth); // 设置圆环的宽度
paint.setColor(roundColor); // 设置圆环的颜色
paint.setAntiAlias(true); // 消除锯齿
// 设置画笔样式
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(centerX, centerX, radius, paint); // 画出圆环

2、绘制渐变色前景圆环(进度环)
代码:

// step2 画圆弧-画圆环的进度
// 锁画布(为了保存之前的画布状态)
canvas.save();
canvas.rotate(startAngle, centerX, centerX);
paint.setStrokeWidth(progressWidth); // 设置画笔的宽度使用进度条的宽度
paint.setColor(progressColor); // 设置进度的颜色
RectF oval = new RectF(centerX - radius, centerX - radius, centerX + radius, centerX + radius); // 用于定义的圆弧的形状和大小的界限int sweepAngle = 360 * progress / max; // 计算进度值在圆环所占的角度
// 根据进度画圆弧
paint.setShader(new SweepGradient(centerX, centerX, new int[]{startColor, midColor, endColor}, null));
canvas.drawArc(oval, 0, sweepAngle, false, paint);
paint.setShader(null);
canvas.rotate(-startAngle, centerX, centerX);
canvas.restore();

作解释如下:

  • canvas.save:保存画布当前状态;
  • canvas.rotate:让画布按point(x,y)点中心旋转某个角度;
  • paint.setShader:给画笔设置着色器,这里设置了一个以(centerX, centerX)点为中心的渐变色着色器;
  • canvas.restore:特殊绘制完成后恢复画布为原来的状态。

SweepGradient类可以绘制出中心渐变效果,但是因为我们的进度条加了startAngle以调整其实角度,所以在给画笔paint添加SweepGradient的shader时,需要提前将画布旋转下,因为SweepGradient只能从默认角度开始出渐变效果。旋转绘制的效果,如下图:

如果画布不旋转的话出来的效果就是起止色不能完全对应。

画布的旋转有涉及到以下3个方法:

android.graphics.Canvas#save()
android.graphics.Canvas#rotate(float, float, float)
android.graphics.Canvas#restore

3、绘制文字及百度比数字
此部分可参考上一篇 Android花样loading进度条(三)-配文字环形进度条中的讲解,此处略过。

至此,渐变色环形进度条绘制就完成了,整个GradientRoundProgress的代码为:

package com.dommy.loading.widget;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;import com.dommy.loading.R;
import com.dommy.loading.util.AppResource;/*** 渐变色环形进度条*/
public class GradientRoundProgress extends View {private Paint paint; // 画笔对象的引用private int roundColor; // 圆环的颜色private float roundWidth; // 圆环的宽度private int progressColor; // 圆环进度的颜色private float progressWidth; // 圆环进度的宽度private String text; // 文字内容private int textColor; // 中间进度百分比的字符串的颜色private float textSize; // 中间进度百分比的字符串的字体大小private float numSize; // 中间进度文本大小private int max; // 最大进度private int startAngle; // 进度条起始角度private boolean textShow; // 是否显示中间的进度private boolean useCustomFont; // 是否使用自定义字体private int startColor; // 渐变色起始色private int midColor; // 渐变色中间色private int endColor; // 渐变色起始色private int progress; // 当前进度public GradientRoundProgress(Context context) {this(context, null);}public GradientRoundProgress(Context context, AttributeSet attrs) {this(context, attrs, 0);}public GradientRoundProgress(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);paint = new Paint();// 读取自定义属性的值TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.GradientRoundProgress);// 获取自定义属性和默认值roundColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_roundColor, Color.RED);roundWidth = mTypedArray.getDimension(R.styleable.GradientRoundProgress_grp_roundWidth, 5);progressColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_progressColor, Color.GREEN);progressWidth = mTypedArray.getDimension(R.styleable.GradientRoundProgress_grp_progressWidth, roundWidth);text = mTypedArray.getString(R.styleable.GradientRoundProgress_grp_text);textColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_textColor, Color.GREEN);textSize = mTypedArray.getDimension(R.styleable.GradientRoundProgress_grp_textSize, 11);numSize = mTypedArray.getDimension(R.styleable.GradientRoundProgress_grp_numSize, 14);max = mTypedArray.getInteger(R.styleable.GradientRoundProgress_grp_max, 100);startAngle = mTypedArray.getInt(R.styleable.GradientRoundProgress_grp_startAngle, 90);textShow = mTypedArray.getBoolean(R.styleable.GradientRoundProgress_grp_textShow, true);useCustomFont = mTypedArray.getBoolean(R.styleable.GradientRoundProgress_grp_userCustomFont, false);startColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_startColor, Color.GREEN);midColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_midColor, Color.GREEN);endColor = mTypedArray.getColor(R.styleable.GradientRoundProgress_grp_endColor, Color.GREEN);mTypedArray.recycle();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int centerX = getWidth() / 2; // 获取圆心的x坐标int radius = (int) (centerX - roundWidth / 2); // 圆环的半径// step1 画最外层的大圆环paint.setStrokeWidth(roundWidth); // 设置圆环的宽度paint.setColor(roundColor); // 设置圆环的颜色paint.setAntiAlias(true); // 消除锯齿// 设置画笔样式paint.setStyle(Paint.Style.STROKE);canvas.drawCircle(centerX, centerX, radius, paint); // 画出圆环// step2 画圆弧-画圆环的进度// 锁画布(为了保存之前的画布状态)canvas.save();canvas.rotate(startAngle, centerX, centerX);paint.setStrokeWidth(progressWidth); // 设置画笔的宽度使用进度条的宽度paint.setColor(progressColor); // 设置进度的颜色RectF oval = new RectF(centerX - radius, centerX - radius, centerX + radius, centerX + radius); // 用于定义的圆弧的形状和大小的界限int sweepAngle = 360 * progress / max; // 计算进度值在圆环所占的角度// 根据进度画圆弧paint.setShader(new SweepGradient(centerX, centerX, new int[]{startColor, midColor, endColor}, null));canvas.drawArc(oval, 0, sweepAngle, false, paint);paint.setShader(null);canvas.rotate(-startAngle, centerX, centerX);canvas.restore();// step3 画文字指示paint.setStrokeWidth(0);paint.setColor(textColor);paint.setTextSize(textSize);// 计算百分比int percent = (int) (((float) progress / (float) max) * 100);if (textShow && text != null && text.length() > 0 && percent >= 0) {// 3.1 画文字paint.setTypeface(Typeface.DEFAULT); // 设置为默认字体float textWidth = paint.measureText(text); // 测量字体宽度canvas.drawText(text, centerX - textWidth / 2, centerX + textSize + 5, paint);// 3.2 画百分比paint.setTextSize(numSize);if (useCustomFont) {paint.setTypeface(AppResource.getTypeface(getContext())); // 设置字体} else {paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置为加粗默认字体}float numWidth = paint.measureText(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间canvas.drawText(percent + "%", centerX - numWidth / 2, centerX, paint); // 画出进度百分比}}/*** 设置进度的最大值* <p>根据需要,最大值一般设置为100,也可以设置为1000、10000等</p>** @param max int最大值*/public synchronized void setMax(int max) {if (max < 0) {throw new IllegalArgumentException("max not less than 0");}this.max = max;}/*** 获取进度** @return int 当前进度值*/public synchronized int getProgress() {return progress;}/*** 设置进度,此为线程安全控件** @param progress 进度值*/public synchronized void setProgress(int progress) {if (progress < 0) {throw new IllegalArgumentException("progress not less than 0");}if (progress > max) {progress = max;}this.progress = progress;// 刷新界面调用postInvalidate()能在非UI线程刷新postInvalidate();}
}

渐变色环形进度条的使用

1、页面控件配置
自定义控件在页面中使用时,要使用类名来作为标签,自定义属性要通过命名空间引入,整体如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"...tools:context="com.dommy.loading.GradientRoundActivity">...<com.dommy.loading.widget.GradientRoundProgressandroid:id="@+id/grp_0"android:layout_width="100dip"android:layout_height="100dip"android:layout_gravity="center"app:grp_endColor="@color/gr_end"app:grp_midColor="@color/gr_mid"app:grp_startColor="@color/gr_start"app:grp_max="100"app:grp_numSize="22sp"app:grp_progressColor="@color/red_web"app:grp_roundColor="@color/pro_bg"app:grp_roundWidth="6dip"app:grp_startAngle="0"app:grp_text="空气质量"app:grp_textColor="@color/red_web"app:grp_textSize="10sp" />...
</LinearLayout>

页面编写时的preview效果:

2、Activity代码控制
通过调用方法

com.dommy.loading.widget.GradientRoundProgress#setProgress

就可以设置控件显示指定的进度,如:

grp0.setProgress(50);

3、让进度动起来
通过Thread+Handler动态增加的方法,不断更新界面就可以达到动起来的效果:

改变效果

进度的宽度、颜色、字体大小等可以通过自定义属性直接修改。

源码下载

https://github.com/ahuyangdong/ColorfulLoading

Android花样loading进度条(四)-渐变色环形进度条相关推荐

  1. Android花样loading进度条(二)-简单环形进度条

    背景 Android花样loading进度条系列文章主要讲解如何自定义所需的进度条,包括水平.圆形.环形.圆弧形.不规则形状等. 本篇我们从圆形进度条讲起,讲简单形式的环形进度条,只有进度色彩,没有进 ...

  2. vue圆环进度条_vue圆环形进度条组件

    1.先来个圆形背景,为了后续方便定位,请给它安排上position属性. CircleProgress.vue export default { name: "circle-progress ...

  3. ios swift 实现饼状图进度条,swift环形进度条

    ios swift 实现饼状图进度条 // // ProgressControl.swift // L02MyProgressControl // // Created by plter on 7/2 ...

  4. Android开发笔记(十四)圆弧进度动画CircleAnimation

    一个好看的APP,都有不少精致的动画效果.熟练运用各种动画技术,可让我们的APP灼灼生辉.Android在技术上把动画分为了三类,分别是帧动画FrameAnimation.补间动画TweenAnima ...

  5. 仿MIUI音量变化环形进度条实现

    Android中使用环形进度条的业务场景事实上蛮多的,比方下载文件的时候使用环形进度条.会给用户眼前一亮的感觉:再比方我大爱的MIUI系统,它的音量进度条就是使用环形进度条,尽显小米"为发烧 ...

  6. MFC环形进度条实现

    MFC只支持横/竖条形进度条,并不支持环形进度条,而环形进度条在实际中使用很是广泛,以下使用GDI+自绘具有环形效果的进度条. 其实GDI+里封装有一个函数DrawArc可以画环形进度条,但它有一个缺 ...

  7. android canvas_Android 自定义View篇(七)实现环形进度条效果

    前言 Android 自定义 View 是高级进阶不可或缺的内容,日常工作中,经常会遇到产品.UI 设计出花里胡哨的界面.当系统自带的控件不能满足开发需求时,就只能自己动手撸一个效果. 本文就带自定义 ...

  8. Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改

    Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改 首先我们来看下效果图 不同的开口大小只需要修改一个参数即可 半圆1: 半圆2: 半圆3: 如果是你想要的效果,就直接滑动 ...

  9. android绘制环形进度_Android使用Canvas绘制圆形进度条效果

    前言 Android自定义控件经常会用到Canvas绘制2D图形,在优化自己自定义控件技能之前,必须熟练掌握Canvas绘图机制.本文从以下三个方面对Canvas绘图机制进行讲解: 画布Canvas ...

最新文章

  1. 桌面支持--ZWMECH软件卸载工具
  2. linq之join子句
  3. 窗口分析函数_13_生成相邻上一个元素
  4. [Python从零到壹] 八.数据库之MySQL和Sqlite基础知识及操作万字详解
  5. manually create IBASE 03 in CRM
  6. linux中wine yum安装,分享|在基于RedHat或Debian的系统上安装 Wine 1.7
  7. Red5 修改RTMP监听端口和ip
  8. android开启热点softap模式,[RK3288][Android6.0] Wifi开启热点(SoftAP)流程小结
  9. Python垃圾回收(gc)拖累了程序执行性能?
  10. Qt QLCDNumber 13行实现 显示日期时间 颜色设置 刷新
  11. SPSS参数检验、非参数检验、方差分析
  12. 安装VMware虚拟机及镜像文件
  13. 微信小程序组件间传值
  14. 检测本计算机的IP地址,告诉您如何使用命令检查本地IP地址
  15. 华为和小米:在智能电视市场的边缘疯狂试探
  16. mysql explain不准确_mysql explain预估剖析
  17. 【2019-TGRS】Aerial LaneNet: Lane-Marking Semantic Segmentation in Aerial Imagery Using Wavelet-Enhanc
  18. 外部js文件中调用pinia时,报错getActivePinia was called with no active Pinia. Did you forget to install pinia?
  19. filebeat7.7.0相关详细配置预览- processors - rename
  20. 计算机专业证书难度,计算机专业应该考这些证书!

热门文章

  1. Linux中网卡未激活解决方案
  2. pdm系统是归档服务器吗,PDM系统与档案管理系统集成方法研究
  3. 宜春市大数据发展管理局局长丁朝科一行莅临麒麟信安调研
  4. NOIP2014-提高组初赛C语言解析(选择填空题)
  5. 设置360浏览器打开html 默认显示为极速模式
  6. linux查看cpu核心电压,来感受Linux命令行的“真香定律”
  7. 惠普hp战66拆机(含主板)
  8. Elasticsearch慢查询分析
  9. Pipenv永久配置镜像源与python版本
  10. 华为游戏浮标不显示或显示异常