带颜色渐变效果的的矩形进度条

来源:互联网 发布:个人工作记录软件 编辑:程序博客网 时间:2024/05/29 02:27

先看一下效果:


有没有亮瞎你的眼?

嗯...我说结尾的颜色。


先分析下实现的逻辑:我们用一个Drawable对象设置为button的背景;→Drawable对象我们取它的子类BitmapDrawable的一个实例,BitmapDrawAble需要一个Bitmap对象;→绘制这个bitmap:有一个外边的框框我们画一个矩形,进度那条线我们使用绘制一个Path来表现;→当前的进度值乘以矩形的周长是path的长度,根据这个长度和矩形周长的关系,使用path的lineTo,moveTo等函数对其进行设置,然后绘制这个path。→颜色根据进度值改变得到一个变化的颜色。


实现细节:

1,得到矩形宽高:在onclick事件中

        w = v.getMeasuredWidth();        h = v.getMeasuredHeight();
2,根据进度得到Path,这里我是以顶部的中点为起点顺时针计算进度的,这里可以随意发挥,周长乘以这个进度得到path的长度,在按照你设计好的起点和方向画线,遇到顶点时判断path需不需要拐弯。

 /**     * 根据百分比得到路径     *     * @param pro 0~1之间的一个浮点数     * @return     */    public Path getPath(float pro) {        pro = pro * (w * 2 + h * 2);        Path p = new Path();        p.moveTo(w / 2, 0);        if (pro < w / 2) {            p.lineTo(w / 2 + pro, 0);            return p;        } else {            p.lineTo(w, 0);        }        if (pro < w / 2 + h) {            p.lineTo(w, (pro - w / 2));            return p;        } else {            p.lineTo(w, h);        }        if (pro < w / 2 + h + w) {            p.lineTo((w - (pro - h - w / 2)), h);            return p;        } else {            p.lineTo(0, h);        }        if (pro < w / 2 + h + h + w) {            p.lineTo(0, h - (pro - w - h - w / 2));            return p;        } else {            p.lineTo(0, 0);        }        p.lineTo(pro - w - h * 2 - w / 2, 0);        return p;    }

3,根据进度得到一个渐变色,渐变色的原理没有搜到,这里模拟了一下,RGB颜色让其中一个或几个通道的颜色值在一定范围内渐变。

   /**     * 得到颜色梯度中间值 这里可以自己定义     *     * @param pro 0~1之间的一个浮点数     * @return     */    public int getColor(float pro) {        int c = Color.argb(255, 100+(int) ((1 - pro) * 130), (int) (pro * 255), 155);        return c;    }

4,得到背景Drawable对象,这里没什么好说的,画笔设置之前根据进度值得到的颜色,设置不同宽度分别画path和矩形。

 /**     * 得到DrawAble对象     *     * @param path     * @param color     * @return     */    public Drawable getBgDrawAble(Path path, int color) {        Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);        Canvas c = new Canvas(b);        Paint paint = new Paint();        paint.setColor(color);        paint.setStrokeWidth(30);        paint.setStyle(Paint.Style.STROKE);        c.drawPath(path, paint);        paint.setStrokeWidth(3);        c.drawRect(0,0,w,h,paint);        BitmapDrawable bd = new BitmapDrawable(b);        return bd;    }
5,这里模拟一个下载的使用场景:

在onclick事件中开启一个异步任务:

 public void download(View v) {        w = v.getMeasuredWidth();        h = v.getMeasuredHeight();        new DownloadTask(v).execute();    }

 class DownloadTask extends AsyncTask<Void, Float, Boolean> {        View v;        public DownloadTask(View v) {            this.v = v;        }        @Override        protected Boolean doInBackground(Void... params) {            for (int i = 0; i <= 200; i++) {                publishProgress(i * 1.0f / 200);                try {                    Thread.sleep(30);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            return true;        }        @Override        protected void onPreExecute() {            super.onPreExecute();            ((Button)v).setClickable(false);// 设置按钮不可点击        }        @Override        protected void onPostExecute(Boolean integer) {            super.onPostExecute(integer);            ((Button)v).setText("下载完成");            ((Button)v).setClickable(true);        }        @Override        protected void onProgressUpdate(Float... values) {            float rate = values[0];            int col = getColor(rate);            ((Button)v).setTextColor(col);            v.setBackground(getBgDrawAble(getPath(rate), col));            ((Button)v).setText("已下载" + (rate < 0.1 ? "0" : "") + (int)(rate*100) + "%");//计算下载进度并设置文字            super.onProgressUpdate(values);        }    }

这个估计是最土的实现方法了,效率神马的待我脑补相关知识再考虑吧。


1 0
原创粉丝点击