最近项目中使用到了渐变效果的圆形进度条,网上找了很多渐变效果不够圆滑,两个渐变颜色之间有明显的过渡,或者有些代码画出来的效果过渡不美观,于是自己参照写了一个,喜欢的朋友可以参考或者直接使用。

先上一张效果图,视频录制不太好,不过不影响效果

下面开始介绍实现代码,比较简单,直接贴代码吧

1、声明自定义属性

在项目的valuse文件夹下新建attrs.xml,在里面定义自定义控件需要的属性

2、自定义一个进度条RoundProgres继承view类

package com.blankj.progressring;

import android.animation.ValueAnimator;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.RectF;

import android.graphics.SweepGradient;

import android.graphics.Typeface;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.view.animation.LinearInterpolator;

import org.jetbrains.annotations.Nullable;

/**

* 类描述:渐变的圆形进度条

*

* @author:lusy

* @date :2018/10/17

*/

public class RoundProgress extends View {

private static final String TAG = "roundProgress";

/**

* 背景圆环画笔

*/

private Paint bgPaint;

/**

* 白色标记画笔

*/

private Paint iconPaint;

/**

* 进度画笔

*/

private Paint progressPaint;

/**

* 进度文本画笔

*/

private Paint textPaint;

/**

* 背景圆环的颜色

*/

private int bgColor;

/**

* 线条进度的颜色

*/

private int iconColor;

private int[] progressColor;

/**

* 中间进度百分比的字符串的颜色

*/

private int textColor;

/**

* 中间进度百分比的字符串的字体大小

*/

private float textSize;

/**

* 圆环的宽度

*/

private float roundWidth;

/**

* 最大进度

*/

private int max;

/**

* 当前进度

*/

private float progress;

/**

* 是否显示中间的进度

*/

private boolean textIsDisplayable;

/**

* 圆环半径

*/

private int mRadius;

private int center;

private float startAngle = -90;

private float currentAngle;

private float currentProgress;

public RoundProgress(Context context) {

this(context, null);

}

public RoundProgress(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);

//获取自定义属性和默认值

bgColor = mTypedArray.getColor(R.styleable.RoundProgress_bgColor, Color.parseColor("#2d2d2d"));

iconColor = mTypedArray.getColor(R.styleable.RoundProgress_lineColor, Color.parseColor("#ffffff"));

textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.parseColor("#ffffff"));

textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15);

roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_roundWidth, 5);

max = mTypedArray.getInteger(R.styleable.RoundProgress_maxProgress, 100);

textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgress_textIsDisplayable, true);

progressColor = new int[]{Color.parseColor("#747eff"), Color.parseColor("#0018ff"), Color.TRANSPARENT};

mTypedArray.recycle();

initPaint();

}

public RoundProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

//测量控件应占的宽高大小,此处非必需,只是为了确保布局中设置的宽高不一致时仍显示完整的圆

int measureWidth = MeasureSpec.getSize(widthMeasureSpec);

int measureHeight = MeasureSpec.getSize(heightMeasureSpec);

setMeasuredDimension(Math.min(measureWidth, measureHeight), Math.min(measureWidth, measureHeight));

}

private void initPaint() {

bgPaint = new Paint();

bgPaint.setStyle(Paint.Style.STROKE);

bgPaint.setAntiAlias(true);

bgPaint.setColor(bgColor);

bgPaint.setStrokeWidth(roundWidth);

iconPaint = new Paint();

iconPaint.setStyle(Paint.Style.STROKE);

iconPaint.setAntiAlias(true);

iconPaint.setColor(iconColor);

iconPaint.setStrokeWidth(roundWidth);

progressPaint = new Paint();

progressPaint.setStyle(Paint.Style.STROKE);

progressPaint.setAntiAlias(true);

progressPaint.setStrokeWidth(roundWidth);

textPaint = new Paint();

textPaint.setStyle(Paint.Style.STROKE);

textPaint.setTypeface(Typeface.DEFAULT_BOLD);

textPaint.setAntiAlias(true);

textPaint.setColor(textColor);

textPaint.setTextSize(textSize);

textPaint.setStrokeWidth(0);

}

@Override

protected void onDraw(Canvas canvas) {

/**

* 画最外层的大圆环

*/

//获取圆心的x坐标

center = Math.min(getWidth(), getHeight()) / 2;

// 圆环的半径

mRadius = (int) (center - roundWidth / 2);

RectF oval = new RectF(center - mRadius, center - mRadius, center + mRadius, center + mRadius);

//画背景圆环

canvas.drawArc(oval, startAngle, 360, false, bgPaint);

//画进度圆环

drawProgress(canvas, oval);

canvas.drawArc(oval, startAngle, currentAngle, false, progressPaint);

//画白色圆环

float start = startAngle + currentAngle - 1;

canvas.drawArc(oval, start, 3, false, iconPaint);

//百分比文字

int percent = (int) (((float) progress / (float) max) * 100);

//测量字体宽度,我们需要根据字体的宽度设置在圆环中间

String text = String.valueOf(percent)+"%";

Rect textRect = new Rect();

textPaint.getTextBounds(text, 0, text.length(), textRect);

if (textIsDisplayable && percent >= 0) {

//画出进度百分比文字

float x = (getWidth() - textRect.width()) / 2;

float y = (getHeight() + textRect.height()) / 2;

canvas.drawText(text, x, y, textPaint);

}

if (currentProgress < progress) {

currentProgress++;

postInvalidate();

}

}

/**

* 画进度圆环

*

* @param canvas

* @param oval

*/

private void drawProgress(Canvas canvas, RectF oval) {

float section = progress / 100;

currentAngle = section * 360;

//把需要绘制的角度分成100等分

float unitAngle = (float) (currentAngle / 100.0);

for (float i = 0, end = currentProgress * unitAngle; i <= end; i++) {

SweepGradient shader = new SweepGradient(center, center, progressColor, new float[]{0.0f, section, 1.0f});

Matrix matrix = new Matrix();

matrix.setRotate(startAngle, center, center);

shader.setLocalMatrix(matrix);

progressPaint.setShader(shader);

canvas.drawArc(oval,

startAngle + i,

1,

false,

progressPaint);

}

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

//计算外圆半径 宽,高最小值-填充边距/2

center = (Math.min(w, h)) / 2;

mRadius = (int) ((Math.min(w, h)) - roundWidth / 2);

}

public int getMax() {

return max;

}

/**

* 设置进度的最大值

*

* @param max

*/

public void setMax(int max) {

if (max < 0) {

Log.e(TAG, "max progress not allow <0");

return;

}

this.max = max;

}

/**

* 获取进度

*

* @return

*/

public float getProgress() {

return progress;

}

/**

* 设置进度

*

* @param progressValue

* @param useAnima 是否需要动画

*/

public void setProgress(float progressValue, boolean useAnima) {

float percent = progressValue * max / 100;

if (percent < 0) {

percent = 0;

}

if (percent > 100) {

percent = 100;

}

//使用动画

if (useAnima) {

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, percent);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

progress = (float) animation.getAnimatedValue();

postInvalidate();

}

});

valueAnimator.setInterpolator(new LinearInterpolator());

valueAnimator.setDuration(1500);

valueAnimator.start();

} else {

this.progress = percent;

postInvalidate();

}

}

public int getTextColor() {

return textColor;

}

public void setTextColor(int textColor) {

this.textColor = textColor;

}

public float getTextSize() {

return textSize;

}

public void setTextSize(float textSize) {

this.textSize = textSize;

}

public float getRoundWidth() {

return roundWidth;

}

public void setRoundWidth(float roundWidth) {

this.roundWidth = roundWidth;

}

public int[] getProgressColor() {

return progressColor;

}

public void setProgressColor(int[] progressColor) {

this.progressColor = progressColor;

postInvalidate();

}

public int getBgColor() {

return bgColor;

}

public void setBgColor(int bgColor) {

this.bgColor = bgColor;

}

public int getIconColor() {

return iconColor;

}

public void setIconColor(int iconColor) {

this.iconColor = iconColor;

}

public boolean isTextIsDisplayable() {

return textIsDisplayable;

}

public void setTextIsDisplayable(boolean textIsDisplayable) {

this.textIsDisplayable = textIsDisplayable;

}

public int getmRadius() {

return mRadius;

}

public void setmRadius(int mRadius) {

this.mRadius = mRadius;

}

public int getCenter() {

return center;

}

public void setCenter(int center) {

this.center = center;

}

public float getStartAngle() {

return startAngle;

}

public void setStartAngle(float startAngle) {

this.startAngle = startAngle;

}

}

3、使用自定义进度条view

activity布局文件使用如下,为了方便测试效果,新增进度加、进度减,修改进度条颜色的按钮

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#242424"

android:gravity="center">

android:id="@+id/buttonLayout"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_margin="20dp"

android:gravity="center_horizontal"

android:orientation="horizontal">

android:id="@+id/addProgress"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="进度+" />

android:id="@+id/changeColor"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="10dp"

android:layout_marginRight="10dp"

android:text="设置颜色" />

android:id="@+id/subtraceProgress"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="进度-" />

android:id="@+id/socProgress"

android:layout_width="70dp"

android:layout_height="70dp"

android:layout_below="@id/buttonLayout"

android:layout_centerHorizontal="true"

android:layout_gravity="center"

android:layout_marginLeft="20dp"

android:layout_marginBottom="2dp"

app:bgColor="@color/bgColor"

app:maxProgress="100"

app:roundWidth="8dp"

app:textIsDisplayable="true"

app:textSize="18sp" />

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

android 圆形渐变背景,android实现圆形渐变进度条相关推荐

  1. android圆形点击效果,Android 三种方式实现自定义圆形页面加载中效果的进度条

    [实例简介] Android 三种方式实现自定义圆形页面加载中效果的进度条 [实例截图] [核心代码] ad376a86-a9aa-49bc-8cea-321bcff2c0c3 └── AnimRou ...

  2. android下载通知栏,Android开发中实现下载文件通知栏显示进度条

    android开发中实现下载文件通知栏显示进度条. 1.使用asynctask异步任务实现,调用publishprogress()方法刷新进度来实现(已优化) public class myasync ...

  3. android仿微信图片上传进度,Android开发之模仿微信打开网页的进度条效果(高仿)...

    一,为什么说是真正的高仿? 阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果",你会看到有很多类似的文章,不过他们有个共同点,就是实 ...

  4. android仿微信 进度条,Android开发之模仿微信打开网页的进度条效果(高仿)

    一,为什么说是真正的高仿? 阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是 ...

  5. android 圆形渐变背景,Android背景渐变色(shape,gradient) 圆角(shape,corners)

    Android设置背景色可以通过在res/drawable里定义一个xml,如下: [代码]xml代码: 1 2 3 4 android:startColor="#FFF" 5 a ...

  6. android设置渐变背景,Android LinearLayout渐变背景

    我在将渐变背景应用于LinearLayout时遇到问题. 根据我所读的内容,这应该相对简单,但似乎不起作用. 作为参考,我正在开发2.1-update1. header_bg.xml: android ...

  7. android自定义透明圆形,Android progressdialog自定义背景透明的圆形进度条类似于Dialog...

    很高兴能为大家分享一个背景是透明的圆形进度,先开效果图 效果图如下: 效果图 实现方法如下: 首先准备自己要定义成哪样子的效果的图片. 圆形进度条 1.创建Dialog的代码,你可以自己封装成一个方法 ...

  8. Android 三种方式实现自定义圆形页面加载中效果的进度条

    转载:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=76872 一.通过动画实现 定义res/anim/loading.xml如 ...

  9. android 半边圆角背景,Android UI(一)Layout 背景局部Shape圆角设计

    Jeff Lee blog:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),retain the url when reproduced ! Thanks ...

最新文章

  1. C++ main函数中参数argc和argv
  2. CKEditor4.4.5 插入高度代码及上传图片
  3. pytorch保存模型pth_Pytorch_trick_04
  4. 论文浅尝 | 多标签分类中的元学习
  5. 求矩阵特征值的方法和性质
  6. 动态规划复习-HDU1081
  7. android eclipse不能创建activity,在eclipse里面开发android应用,不能新建Activity
  8. 人工智能TensorFlow工作笔记005---计算图的基本应用_认识计算图
  9. catia里画铰链_基于CATIA的汽车车门铰链设计
  10. signature=d601b7b6eb512df6319aad970c9aaeab,Excise Tax Return Serial Number 97-17 971101 971115
  11. itunes下载的app在哪里及如何查看iTunes下载的软件
  12. Mixamo不仅是可商用的免费模型动画库,还是一个在线绑定蒙皮神器
  13. 还在搞三层架构?了解下 DDD 分层架构的三种模式吧
  14. t430服务器安装系统,Dell PowerEdge T430
  15. java的像素与dpi_对屏幕的理解---分辨率,dpi,ppi,屏幕尺寸,像素 等
  16. 手游低延迟高性价比蓝牙耳机,300元学生党最爱五款蓝牙耳机
  17. 不要和自己的大脑抗争,将大脑的能耗降到最低
  18. IAP-In App Purchase流程
  19. 结构方程模型(SEM)概述(1)
  20. 荒野求生获得服务器信息,荒野求生游戏问答老贝出海时任务编码 | 手游网游页游攻略大全...

热门文章

  1. 计算机专业人才培养评价意见,谈高职计算机专业人才培养综合评价.pdf
  2. linux怎样收集系统信息,Linux下收集系统和硬件信息的10个实用命令
  3. Windows如何强制关闭电脑全部代理
  4. 123457123457#0#-----com.cym.YuErBaiKe02--前拼后广--育儿百科
  5. 页面加载微信聊天记录图片不显示问题
  6. Python爬虫报错 ImportError: cannot import name Morsel
  7. 自己追加内存【注意事项】
  8. Python爬虫与信息提取(五)爬虫实例:爬取新浪微博热搜排名
  9. 静态pc端页面,你一定用得上的技巧
  10. C++中使用辅助函数寻找最大/最小值:min()、max()、minmax()