Android环形颜色渐变进度条


我的视频课程:《FFmpeg打造Android万能音频播放器》


        距离上次写博客又过了许久的了,懒起来还真是莫法,废话就不说多了,哈哈。今天要讲的就是一种常见的“环形颜色渐变的圆环进度条”,先看看效果就知道是怎样的了,后面也有免积分Demo下载地址



录制得不是很好,所以看着有点卡顿,不过没事,效果已经看得出来了。

首先说说实现的思路吧:

刚开始想做这个的时候还真没什么思路,后来通过分析可以看出,这个其实就是一个大的圆环,只是中间有空隙而已。android绘制圆环很简单,用canvas.drawArc(...)函数就可以;然后就是中间的间隙,其实也简单,绘制的时候控制相应的度数不绘制就可以了(比如:奇数度数不绘制偶数度数就绘制就可以的),这样基本雏形就成功了;然后再是渐变的颜色,使用ArgbEvaluator这个类就可以实现颜色的渐变(最低level 11,现在大多数手机都是4.0以上的了),本列中颜色只分了两段,实际项目中可以根据需求,把颜色多分几段,然后看着就会很平滑的。通过以上的思路就可以实现图中的效果了。当然这个效果也是一个自定义控件。

思路有了 我们就来实现它:

我们还是分步骤把代码贴出来:

一:继承View类,并重写构造方法:

public class CircleView extends View {
public CircleView(Context context) {
		this(context, null, 0);
	}

	public CircleView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
	}
}
二:添加画笔变量并初始化:

private Paint paint;//画笔
	private RectF oval; // RectF对象(圆环)
	private int currentDegree = 0;//当前度数(除360可求百分比)
	@SuppressLint("NewApi")
	private ArgbEvaluator argbEvaluator = new ArgbEvaluator();//颜色渐变插值器
	private int height;//控件高
	private int width;//控件宽
	private int circleWidth;//圆环宽
	
	private final static int strokeWidth = 40;//画笔大小

	private boolean isGradual = true;//是否显示渐变色

public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		//初始化画笔
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.RED);
		oval = new RectF();
		paint.setStrokeWidth(strokeWidth); // 线宽
		paint.setStyle(Paint.Style.STROKE);
		
	}


三:计算大小,通过效果图,我们知道这个veiw是一个正方形的:

//重写onMeasure方法</span>
@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		//计算最小宽度
		height = View.MeasureSpec.getSize(heightMeasureSpec);    
	    width = View.MeasureSpec.getSize(widthMeasureSpec);    
	    
	    if(width >= height)
	    {
	    	circleWidth = height;
	    }
	    else
	    {
	    	circleWidth = width;
	    }
	    
	    setMeasuredDimension(circleWidth,circleWidth);  
	    oval.left = strokeWidth / 2; // 左边
		oval.top = strokeWidth / 2; // 上边
		oval.right = circleWidth - strokeWidth / 2; // 右边
		oval.bottom = circleWidth - strokeWidth / 2; // 下边
		// 自动旋转
		handler.postDelayed(runnable, 500);
	}
四:绘制圆环

@SuppressLint("NewApi")
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		// canvas.drawArc(oval,-90 + currentDegree, 1.3f , false, paint); //绘制圆弧
			for (int i = 0; i < currentDegree; i++) {
				if (!isGradual) {
					if (i < 180) {
						paint.setColor(Color.BLUE);//右半边颜色
					} else {
						paint.setColor(Color.GREEN);//所半边颜色
					}
				} else {
					Integer color = (Integer) argbEvaluator.evaluate(i / 360f, Color.BLUE, Color.GREEN);//颜色插值器(level 11以上才可以用)
					paint.setColor(color);
				}
				if (i % 2 == 0) {
					canvas.drawArc(oval, -90 + i, 1.35f, false, paint); // 绘制圆弧 1.35f是每个色块宽度
				}
			}
			//绘制白色的底部背景
//			if(currentDegree < 360)
//			{
//				paint.setColor(Color.WHITE);//右半边颜色
//				for(int j = currentDegree; j < 360; j++)
//				{
//					if (j % 2 == 0)
//					{
//					canvas.drawArc(oval, -90 + j, 1.35f, false, paint); // 绘制圆弧 1.35f是每个色块宽度
//					}
//				}
//			}
	}


五:设置当前进度(百分比)和是否渐变开关

<span style="white-space:pre">	</span>/**
	 * 根据百分比设置颜色范围
	 * @param pDegree
	 */
	public void setCurrentDegree(float pDegree)
	{
		this.currentDegree = (int)(360f * pDegree);
	}
<span style="white-space:pre">	</span>/**
	 * 颜色是否渐变
	 * @param gradual
	 */
	public void setGradual(boolean gradual)
	{
		this.isGradual = gradual;
	}
六:为了能模仿进度的效果,这里多添加了一个handler来自动更新进度:

<span style="white-space:pre">	</span>Handler handler = new Handler();
	Runnable runnable = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (currentDegree > 360)
				currentDegree = 0;
			invalidate();
			handler.postDelayed(runnable, 6);//6毫秒绘制一次(可以根据需要更改)
			currentDegree++;
		}
	};
这样就完成了所以的功能,根据需求还可以添加其它功能,这里就先这样吧。

这是全部代码(CircleVIew.java):

package com.ywl5320.circledemo;

import android.animation.ArgbEvaluator;
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.os.Handler;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {

	private Paint paint;//画笔
	private RectF oval; // RectF对象(圆环)
	private int currentDegree = 0;//当前度数(除360可求百分比)
	@SuppressLint("NewApi")
	private ArgbEvaluator argbEvaluator = new ArgbEvaluator();//颜色渐变插值器
	private int height;//控件高
	private int width;//控件宽
	private int circleWidth;//圆环宽
	
	private final static int strokeWidth = 40;//画笔大小

	private boolean isGradual = true;//是否显示渐变色

	public CircleView(Context context) {
		this(context, null, 0);
	}

	public CircleView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		//初始化画笔
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.RED);
		oval = new RectF();
		paint.setStrokeWidth(strokeWidth); // 线宽
		paint.setStyle(Paint.Style.STROKE);
		
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		//计算最小宽度
		height = View.MeasureSpec.getSize(heightMeasureSpec);    
	    width = View.MeasureSpec.getSize(widthMeasureSpec);    
	    
	    if(width >= height)
	    {
	    	circleWidth = height;
	    }
	    else
	    {
	    	circleWidth = width;
	    }
	    
	    setMeasuredDimension(circleWidth,circleWidth);  
	    oval.left = strokeWidth / 2; // 左边
		oval.top = strokeWidth / 2; // 上边
		oval.right = circleWidth - strokeWidth / 2; // 右边
		oval.bottom = circleWidth - strokeWidth / 2; // 下边
//自动旋转
//		handler.postDelayed(runnable, 500);
	}

	@SuppressLint("NewApi")
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		// canvas.drawArc(oval,-90 + currentDegree, 1.3f , false, paint); //绘制圆弧
			for (int i = 0; i < currentDegree; i++) {
				if (!isGradual) {
					if (i < 180) {
						paint.setColor(Color.BLUE);//右半边颜色
					} else {
						paint.setColor(Color.GREEN);//所半边颜色
					}
				} else {
					Integer color = (Integer) argbEvaluator.evaluate(i / 360f, Color.BLUE, Color.GREEN);//颜色插值器(level 11以上才可以用)
					paint.setColor(color);
				}
				if (i % 2 == 0) {
					canvas.drawArc(oval, -90 + i, 1.35f, false, paint); // 绘制圆弧 1.35f是每个色块宽度
				}
			}
			//绘制白色的底部背景
//			if(currentDegree < 360)
//			{
//				paint.setColor(Color.WHITE);//右半边颜色
//				for(int j = currentDegree; j < 360; j++)
//				{
//					if (j % 2 == 0)
//					{
//					canvas.drawArc(oval, -90 + j, 1.35f, false, paint); // 绘制圆弧 1.35f是每个色块宽度
//					}
//				}
//			}
	}
	
	/**
	 * 根据百分比设置颜色范围
	 * @param pDegree
	 */
	public void setCurrentDegree(float pDegree)
	{
		this.currentDegree = (int)(360f * pDegree);
	}
	
	/**
	 * 颜色是否渐变
	 * @param gradual
	 */
	public void setGradual(boolean gradual)
	{
		this.isGradual = gradual;
	}

	Handler handler = new Handler();
	Runnable runnable = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (currentDegree > 360)
				currentDegree = 0;
			invalidate();
			handler.postDelayed(runnable, 6);//6毫秒绘制一次(可以根据需要更改)
			currentDegree++;
		}
	};

}



最后是在activity中调用:

布局文件(activity_main.xml):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

    <com.ywl5320.circleviewdemo.CircleView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Activity代码什么都没变:

package com.ywl5320.circleviewdemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}
也可以在activity中获取CircleView,然后设置相应的属性,达到相应的效果。OK,效果及实现了,也挺简单的,Demo免积分下载地址:实例下载










  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ywl5320

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值