zoukankan      html  css  js  c++  java
  • 自定义控件之圆形颜色渐变进度条--SweepGradient

    前几天在群里面有人找圆形可颜色渐变进度条,其中主要的知识点是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

  • 相关阅读:
    数据库设计 概念结构设计(以权限系统为例)
    sp_addlinkedserver使用方法
    动态页面静态化技术(很不错的教程摘录)
    C#获取硬件序列号
    [转]消息队列关于MSMQ的基础知识
    通过Image对象获取对象的格式
    历史项目的回忆 2008.04.27
    解决Access to Message Queuing system is denied.权限问题
    windows 输入法生成器 导出输入法的mb文件到txt
    [转载]C#版可调节的文字阴影特效
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/5021872.html
Copyright © 2011-2022 走看看