博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义控件之圆形颜色渐变进度条--SweepGradient
阅读量:6712 次
发布时间:2019-06-25

本文共 15518 字,大约阅读时间需要 51 分钟。

 

前几天在群里面有人找圆形可颜色渐变进度条,其中主要的知识点是SweepGradient;

mSweepGradient = new SweepGradient(240, 360, new int[] {
  Color.CYAN,   Color.DKGRAY,   Color.GRAY,   Color.LTGRAY,   Color.MAGENTA,   Color.GREEN,   Color.TRANSPARENT,   Color.BLUE },    null);

如上:第三个参数为渐变颜色内容,前两个是坐标信息,240:渲染中心点x 坐标;360:渲染中心y 点坐标。

 

先绘制圆形:

package com.soyoungboy.sweepgradientprogress;import android.content.Context;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.EmbossMaskFilter;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/** * 圆形颜色渐变的进度条 * @author soyoungboy * */public class SweepGradientCircleProgressBar extends View {    private Paint pathPaint;    private Paint fillArcPaint;    // 设置光源的方向    private float[] direction = new float[] {1, 1, 1};    // 设置环境光亮度    private float light = 0.4f;    // 选择要应用的反射等级    private float specular = 6;    private EmbossMaskFilter emboss;    private RectF oval ;    private BlurMaskFilter mBlur;    // view重绘的标记    private boolean reset = false;    // 向 mask应用一定级别的模糊    private float blur = 3.5f;    private int arcradus = 30;    public SweepGradientCircleProgressBar(Context context ,AttributeSet attrs) {        super(context,attrs);        initPaint();        oval = new RectF();        emboss = new EmbossMaskFilter(direction, light, specular, blur);        mBlur = new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL);    }    //初始化画笔操作    private void initPaint() {        //初始化画笔操作        pathPaint = new Paint();        // 设置是否抗锯齿        pathPaint.setAntiAlias(true);        // 帮助消除锯齿        pathPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        pathPaint.setStyle(Paint.Style.STROKE);        pathPaint.setDither(true);        pathPaint.setStrokeJoin(Paint.Join.ROUND);        fillArcPaint = new Paint();        // 设置是否抗锯齿        fillArcPaint.setAntiAlias(true);        // 帮助消除锯齿        fillArcPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        fillArcPaint.setStyle(Paint.Style.STROKE);        fillArcPaint.setDither(true);        fillArcPaint.setStrokeJoin(Paint.Join.ROUND);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int height = getMeasuredWidth();        int width = getMeasuredWidth();        //半径 = 宽/2-圆环的宽度        int radius = width/2-arcradus;        int cx = width/2;        int cy = height/2;        //绘制画笔颜色        pathPaint.setColor(Color.RED);        //画笔的宽度        pathPaint.setStrokeWidth(10);        pathPaint.setMaskFilter(emboss);        canvas.drawCircle(cx, cy, radius, pathPaint);    }}

 

效果如下:

在上面基础上,绘制大圆和小圆:

package com.soyoungboy.sweepgradientprogress;import android.content.Context;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.EmbossMaskFilter;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/** * 圆形颜色渐变的进度条 * @author soyoungboy * */public class SweepGradientCircleProgressBar extends View {    private Paint pathPaint;    private Paint fillArcPaint;    // 设置光源的方向    private float[] direction = new float[] {1, 1, 1};    // 设置环境光亮度    private float light = 0.4f;    // 选择要应用的反射等级    private float specular = 6;    private EmbossMaskFilter emboss;    private RectF oval ;    private BlurMaskFilter mBlur;    // view重绘的标记    private boolean reset = false;    // 向 mask应用一定级别的模糊    private float blur = 3.5f;    private int arcradus = 30;    public SweepGradientCircleProgressBar(Context context ,AttributeSet attrs) {        super(context,attrs);        initPaint();        oval = new RectF();        emboss = new EmbossMaskFilter(direction, light, specular, blur);        mBlur = new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL);    }    //初始化画笔操作    private void initPaint() {        //初始化画笔操作        pathPaint = new Paint();        // 设置是否抗锯齿        pathPaint.setAntiAlias(true);        // 帮助消除锯齿        pathPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        pathPaint.setStyle(Paint.Style.STROKE);        pathPaint.setDither(true);        pathPaint.setStrokeJoin(Paint.Join.ROUND);        fillArcPaint = new Paint();        // 设置是否抗锯齿        fillArcPaint.setAntiAlias(true);        // 帮助消除锯齿        fillArcPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        fillArcPaint.setStyle(Paint.Style.STROKE);        fillArcPaint.setDither(true);        fillArcPaint.setStrokeJoin(Paint.Join.ROUND);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (reset) {            canvas.drawColor(Color.TRANSPARENT);            reset = false;        }        drawcircle(canvas);    }    private void drawcircle(Canvas canvas) {        int height = getMeasuredWidth();        int width = getMeasuredWidth();        //半径 = 宽/2-圆环的宽度        int radius = width/2-arcradus;        int cx = width/2;        int cy = height/2;        //绘制画笔颜色        pathPaint.setColor(Color.RED);        //画笔的宽度        pathPaint.setStrokeWidth(1);        pathPaint.setMaskFilter(emboss);        canvas.drawCircle(cx, cy, radius, pathPaint);        pathPaint.setColor(Color.BLUE);        //绘制大圆        canvas.drawCircle(width / 2, height / 2, radius + arcradus                / 2 + 0.5f, pathPaint);        //绘制小圆        canvas.drawCircle(width / 2, height / 2, radius - arcradus                / 2 - 0.5f, pathPaint);    }}

效果:

 

去掉绘制中间圆,并不会圆弧:

package com.soyoungboy.sweepgradientprogress;import android.content.Context;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.EmbossMaskFilter;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.SweepGradient;import android.util.AttributeSet;import android.view.View;/** * 圆形颜色渐变的进度条 * @author soyoungboy * */public class SweepGradientCircleProgressBar extends View {    private Paint pathPaint;    private Paint fillArcPaint;    // 设置光源的方向    private float[] direction = new float[] {1, 1, 1};    // 设置环境光亮度    private float light = 0.4f;    //渐变数组    private int[] arcColors = new int[] {Colors.RED,Colors.RED_TRANSLUCENT    };    // 选择要应用的反射等级    private float specular = 6;    private EmbossMaskFilter emboss;    private RectF oval ;    private BlurMaskFilter mBlur;    // view重绘的标记    private boolean reset = false;    // 向 mask应用一定级别的模糊    private float blur = 3.5f;    private int arcradus = 30;    public SweepGradientCircleProgressBar(Context context ,AttributeSet attrs) {        super(context,attrs);        initPaint();        oval = new RectF();        emboss = new EmbossMaskFilter(direction, light, specular, blur);        mBlur = new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL);    }    //初始化画笔操作    private void initPaint() {        //初始化画笔操作        pathPaint = new Paint();        // 设置是否抗锯齿        pathPaint.setAntiAlias(true);        // 帮助消除锯齿        pathPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        pathPaint.setStyle(Paint.Style.STROKE);        pathPaint.setDither(true);        pathPaint.setStrokeJoin(Paint.Join.ROUND);        fillArcPaint = new Paint();        // 设置是否抗锯齿        fillArcPaint.setAntiAlias(true);        // 帮助消除锯齿        fillArcPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        fillArcPaint.setStyle(Paint.Style.STROKE);        fillArcPaint.setDither(true);        fillArcPaint.setStrokeJoin(Paint.Join.ROUND);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (reset) {            canvas.drawColor(Color.TRANSPARENT);            reset = false;        }        drawcircle(canvas);    }    private void drawcircle(Canvas canvas) {        int height = getMeasuredWidth();        int width = getMeasuredWidth();        //半径 = 宽/2-圆环的宽度        int radius = width/2-arcradus;        int cx = width/2;        int cy = height/2;        pathPaint.setColor(Color.BLUE);        //绘制大圆        canvas.drawCircle(width / 2, height / 2, radius + arcradus                / 2 + 0.5f, pathPaint);        //绘制小圆        canvas.drawCircle(width / 2, height / 2, radius - arcradus                / 2 - 0.5f, pathPaint);        // 环形颜色填充        SweepGradient sweepGradient =                new SweepGradient(width / 2, height / 2, arcColors, null);        fillArcPaint.setShader(sweepGradient);        // 设置画笔为白色        // 模糊效果        fillArcPaint.setMaskFilter(mBlur);        // 设置线的类型,边是圆的        fillArcPaint.setStrokeCap(Paint.Cap.ROUND);        //设置圆弧的宽度        fillArcPaint.setStrokeWidth(arcradus+1);        // 确定圆弧的绘制位置,也就是里面圆弧坐标和外面圆弧坐标          oval.set(width / 2 - radius, height / 2 - radius, width                / 2 + radius, height / 2 + radius);        // 画圆弧,第二个参数为:起始角度,第三个为跨的角度,第四个为true的时候是实心,false的时候为空心        canvas.drawArc(oval,                0,                ((float)300 /360 ) * 360,                false,                fillArcPaint);    }}

效果如下:

 

尼玛,丑爆了。

 控制进度的显示,主要是progress和max之间的配合,通过外部设置progress进度来控制进度条的动态:

上面代码修改成如下:

package com.soyoungboy.sweepgradientprogress;import android.content.Context;import android.graphics.BlurMaskFilter;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.EmbossMaskFilter;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.SweepGradient;import android.util.AttributeSet;import android.view.View;/** * 圆形颜色渐变的进度条 * @author soyoungboy * */public class SweepGradientCircleProgressBar extends View {    private Paint pathPaint;    private Paint fillArcPaint;    // 设置光源的方向    private float[] direction = new float[] {1, 1, 1};    // 设置环境光亮度    private float light = 0.4f;    //渐变数组    private int[] arcColors = new int[] {Colors.RED,Colors.RED_TRANSLUCENT    };    // 选择要应用的反射等级    private float specular = 6;    private EmbossMaskFilter emboss;    private RectF oval ;    private BlurMaskFilter mBlur;    // view重绘的标记    private boolean reset = false;    // 向 mask应用一定级别的模糊    private float blur = 3.5f;    private int arcradus = 30;    //初始化进度    private int progress = 0;    //设置进度最大值    private int max = 100;    public SweepGradientCircleProgressBar(Context context ,AttributeSet attrs) {        super(context,attrs);        initPaint();        oval = new RectF();        emboss = new EmbossMaskFilter(direction, light, specular, blur);        mBlur = new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL);    }    //初始化画笔操作    private void initPaint() {        //初始化画笔操作        pathPaint = new Paint();        // 设置是否抗锯齿        pathPaint.setAntiAlias(true);        // 帮助消除锯齿        pathPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        pathPaint.setStyle(Paint.Style.STROKE);        pathPaint.setDither(true);        pathPaint.setStrokeJoin(Paint.Join.ROUND);        fillArcPaint = new Paint();        // 设置是否抗锯齿        fillArcPaint.setAntiAlias(true);        // 帮助消除锯齿        fillArcPaint.setFlags(Paint.ANTI_ALIAS_FLAG);        // 设置中空的样式        fillArcPaint.setStyle(Paint.Style.STROKE);        fillArcPaint.setDither(true);        fillArcPaint.setStrokeJoin(Paint.Join.ROUND);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (reset) {            canvas.drawColor(Color.TRANSPARENT);            reset = false;        }        drawcircle(canvas);    }    private void drawcircle(Canvas canvas) {        int height = getMeasuredWidth();        int width = getMeasuredWidth();        //半径 = 宽/2-圆环的宽度        int radius = width/2-arcradus;        int cx = width/2;        int cy = height/2;        pathPaint.setColor(Color.BLUE);        //绘制大圆        canvas.drawCircle(width / 2, height / 2, radius + arcradus                / 2 + 0.5f, pathPaint);        //绘制小圆        canvas.drawCircle(width / 2, height / 2, radius - arcradus                / 2 - 0.5f, pathPaint);        // 环形颜色填充        SweepGradient sweepGradient =                new SweepGradient(width / 2, height / 2, arcColors, null);        fillArcPaint.setShader(sweepGradient);        // 设置画笔为白色        // 模糊效果        fillArcPaint.setMaskFilter(mBlur);        // 设置线的类型,边是圆的        fillArcPaint.setStrokeCap(Paint.Cap.ROUND);        //设置圆弧的宽度        fillArcPaint.setStrokeWidth(arcradus+1);        // 确定圆弧的绘制位置,也就是里面圆弧坐标和外面圆弧坐标          oval.set(width / 2 - radius, height / 2 - radius, width                / 2 + radius, height / 2 + radius);        // 画圆弧,第二个参数为:起始角度,第三个为跨的角度,第四个为true的时候是实心,false的时候为空心        canvas.drawArc(oval,                0,                ((float)progress /max ) * 360,                false,                fillArcPaint);    }    public int getProgress() {        return progress;    }    public void setProgress(int progress) {        this.progress = progress;        this.invalidate();    }    public int getMax() {        return max;    }    public void setMax(int max) {        this.max = max;    }    /**     * 描述:重置进度     *      * @throws     */    public void reset() {        reset = true;        this.progress = 0;        this.invalidate();    }}

activity代码:

package com.soyoungboy.sweepgradientprogress;import android.os.Bundle;import android.os.Handler;import android.app.Activity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener{    private SweepGradientCircleProgressBar progress;    private Button resetBtn;    // 最大100    private int max = 100;    private int myProgress = 0;    private Handler handler = new Handler() {        public void handleMessage(android.os.Message msg) {            switch (msg.what) {            case 1:                startAddProgress();                break;            default:                break;            }        };    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        progress = (SweepGradientCircleProgressBar) findViewById(R.id.progress);        resetBtn = (Button) findViewById(R.id.resetBtn);        resetBtn.setOnClickListener(this);        startAddProgress();    }    private void startAddProgress() {        myProgress = myProgress + 10;        progress.setProgress(myProgress);        handler.sendEmptyMessageDelayed(1, 1000);    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.resetBtn:            //重置操作            myProgress = 0;            progress.reset();            break;        default:            break;        }    }}

效果如下:

增加控制颜色的代码:

public int[] getArcColors() {        return arcColors;    }    public void setArcColors(int[] arcColors) {        this.arcColors = arcColors;    }

activity中使用:

private void startAddProgress() {        myProgress = myProgress + 10;        progress.setProgress(myProgress);                int[] arcColors = new int[]{                Color.parseColor("#99cccc"),                Color.parseColor("#ccffff"),                Color.parseColor("#ffcccc"),                Color.parseColor("#6699cc"),                Color.parseColor("#99ccff"),                Color.parseColor("#6699cc"),                Color.parseColor("#cc6699"),                Color.parseColor("#ffff00")        };        progress.setArcColors(arcColors );        handler.sendEmptyMessageDelayed(1, 1000);    }

效果如下:

为了不至于开头那段颜色那么突兀,也就是丑,可以修改代码中颜色数组,将颜色数组第一个颜色 = 最后一个颜色,就完美了,就好看了

Demo放到github上面: 

https://github.com/soyoungboy/SweepGradientProgress

转载地址:http://qcolo.baihongyu.com/

你可能感兴趣的文章
中美贸易战升级 医疗器械行业影响大
查看>>
exportfs命令、NFS客户端问题、FTP介绍、使用vsftpd搭建ftp
查看>>
嵌入的iframe框架自适应宽度代码
查看>>
IPTABLES常用命令之配置生产环境IPTABLES及优化
查看>>
linux服务ssh详解
查看>>
cat命令一些不常用但很有用的参数
查看>>
linux文件的类型笔记
查看>>
UNIX/Linux 系统管理技术手册阅读(五)
查看>>
Scala之继承
查看>>
nginx日志统计分析
查看>>
linux密码策略
查看>>
git在本地仓库直接使用rm彻底删除文件,服务端还是存在
查看>>
双色球 脱壳加去效验
查看>>
php安装使用memcached
查看>>
#22 系统进程调度、at、batch、mail、crontab
查看>>
Intellij IDEA Debug调试技巧
查看>>
OPENSSL问题,使用fsockopen()函数提示错误
查看>>
lvs详细介绍
查看>>
ci框架hook钩子
查看>>
PHP Warning: PHP Startup: unable to load dynamic library
查看>>