博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Material Design学习之 ProgreesBar
阅读量:5900 次
发布时间:2019-06-19

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

转载奇怪注明出处:

继续我们Material Design的内容,这一篇讲的是进度条,上一篇是Switch地址例如以下:


进度和动态

在用户能够查看并与内容进行交互之前。尽可能地降低视觉上的变化,尽量使应用载入过程令人愉快。每次操作仅仅能由一个活动指示器呈现。比如,对于刷新操作,你不能即用刷新条,又用动态圆圈来指示。

指示器类型

在操作中,对于完毕部分能够确定的情况下,使用确定的指示器,他们能让用户对某个操作所须要的时间有个高速的了解。

在操作中。对于完毕部分不确定的情况下。用户须要等待一定的时间。无需告知后用户台的情况以及所需时间,这时能够使用不确定的指示器。

指示器的类型有两种:线形进度指示器和圆形进度指示器。

你能够使用当中不论什么一项来指示确定性和不确定性的操作。

线形进度指示器

线形进度指示器应始终从 0% 到 100% 显示。绝不能从高到低反着来。

假设一个队列里有多个正在进行的操作,使用一个进度指示器来指示总体的所须要等待的时间。

这样,当指示器达到 100% 时,它不会返回到0%再又一次開始。

线形进度条应该放置在页眉或某块区域的边缘。

贴2个官方的演示:

条状的

这里写图片描写叙述

环状的

这里写图片描写叙述

样例的实现

这里写图片描写叙述

高防高仿,包结构:

这里写图片描写叙述

OK,我们来看下代码(解释就解释 环状的。条状的比較简单)。

final static String ANDROIDXML = "http://schemas.android.com/apk/res/android";    int backgroundColor = Color.parseColor("#1E88E5");    public ProgressBarCircularIndeterminate(Context context, AttributeSet attrs) {        super(context, attrs);        setAttributes(attrs);    }

21-30,构造函数以及调用初始化的方法

protected void setAttributes(AttributeSet attrs){        setMinimumHeight(Utils.dpToPx(32, getResources()));        setMinimumWidth(Utils.dpToPx(32, getResources()));        //Set background Color        // Color by resource        int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML,"background",-1);        if(bacgroundColor != -1){            setBackgroundColor(getResources().getColor(bacgroundColor));        }else{            // Color by hexadecimal            int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);            if (background != -1)                setBackgroundColor(background);            else                setBackgroundColor(Color.parseColor("#1E88E5"));        }        setMinimumHeight(Utils.dpToPx(3, getResources()));    }

33-55行,获取xml的參数设置颜色,设置大小的最小值。

protected int makePressColor(){        int r = (this.backgroundColor >> 16) & 0xFF;        int g = (this.backgroundColor >> 8) & 0xFF;        int b = (this.backgroundColor >> 0) & 0xFF;//      r = (r+90 > 245) ?

245 : r+90;

// g = (g+90 > 245) ? 245 : g+90; // b = (b+90 > 245) ? 245 : b+90; return Color.argb(128,r, g, b); }

61-79行,颜色渐变的实现,第一次出现时调用。

@Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if(firstAnimationOver == false)            drawFirstAnimation(canvas);        if(cont > 0)            drawSecondAnimation(canvas);        invalidate();    }

72-81行。详细绘制的操作,由于要推断是否第一次,所以调用了2种不同的方法,我们一个个看。

float radius1 = 0;    float radius2 = 0;    int cont = 0;    boolean firstAnimationOver = false;    /**     * Draw first animation of view     * @param canvas     */    private void drawFirstAnimation(Canvas canvas){        if(radius1 < getWidth()/2){            Paint paint = new Paint();            paint.setAntiAlias(true);            paint.setColor(makePressColor());            radius1 = (radius1 >= getWidth()/2)? (float)getWidth()/2 : radius1+1;            canvas.drawCircle(getWidth()/2, getHeight()/2, radius1, paint);        }else{            Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);            Canvas temp = new Canvas(bitmap);            Paint paint = new Paint();            paint.setAntiAlias(true);            paint.setColor(makePressColor());            temp.drawCircle(getWidth()/2, getHeight()/2, getHeight()/2, paint);            Paint transparentPaint = new Paint();            transparentPaint.setAntiAlias(true);            transparentPaint.setColor(getResources().getColor(android.R.color.transparent));            transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));            if(cont >= 50){                radius2 = (radius2 >= getWidth()/2)? (float)getWidth()/2 : radius2+1;            }else{                radius2 = (radius2 >= getWidth()/2-Utils.dpToPx(4, getResources()))? (float)getWidth()/2-Utils.dpToPx(4, getResources()) : radius2+1;            }            temp.drawCircle(getWidth()/2, getHeight()/2, radius2, transparentPaint);            canvas.drawBitmap(bitmap, 0, 0, new Paint());            if(radius2 >= getWidth()/2-Utils.dpToPx(4, getResources()))                cont++;            if(radius2 >= getWidth()/2)                firstAnimationOver = true;        }    }

83-121,第一次绘制会调用的方法。

假设圆的radius有大小则依据尺寸来绘画没有就依据空间大小来设定大小(一開始肯定是0。然后慢慢自增,也就是我们那个灰色圈渐渐变大的效果)

当增长到一定程度了,就開始绘画空心圆部分的操作,空心圆也是渐渐掏空,直至全然达到控件实体的大小动画才停止。整个变化过彻骨结束之后把推断是否为第一次的firstAnimationOver状态改变

整个过程invalidate();使得逻辑不断运行。

int arcD = 1;    int arcO = 0;    float rotateAngle = 0;    int limite = 0;    /**     * Draw second animation of view     * @param canvas     */    private void drawSecondAnimation(Canvas canvas){        if(arcO == limite)            arcD+=6;        if(arcD >= 290 || arcO > limite){            arcO+=6;            arcD-=6;        }        if(arcO > limite + 290){            limite = arcO;            arcO = limite;            arcD = 1;        }        rotateAngle += 4;        canvas.rotate(rotateAngle,getWidth()/2, getHeight()/2);        Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);        Canvas temp = new Canvas(bitmap);        Paint paint = new Paint();        paint.setAntiAlias(true);        paint.setColor(backgroundColor);//      temp.drawARGB(0, 0, 0, 255);        temp.drawArc(new RectF(0, 0, getWidth(), getHeight()), arcO, arcD, true, paint);        Paint transparentPaint = new Paint();        transparentPaint.setAntiAlias(true);        transparentPaint.setColor(getResources().getColor(android.R.color.transparent));        transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));        temp.drawCircle(getWidth()/2, getHeight()/2, (getWidth()/2)- Utils.dpToPx(4, getResources()), transparentPaint);        canvas.drawBitmap(bitmap, 0, 0, new Paint());    }

131-160,非第一次绘制时的实现,这边我来解释下重要部分的逻辑。

if(arcO == limite)            arcD+=6;        if(arcD >= 290 || arcO > limite){            arcO+=6;            arcD-=6;        }        if(arcO > limite + 290){            limite = arcO;            arcO = limite;            arcD = 1;        }

大圆弧最大值为290,满了就收缩,究竟到头了都增长,用2个变量做差值反向计算,290为边界值

canvas.rotate(rotateAngle,getWidth()/2, getHeight()/2);

旋转操作,每一次角度自增4

分析:

就是第一次进去画一个从圆心缩放的效果。然后之后都是走290圆弧增大缩小的无限循环计算绘画,计算这部分逻辑还是有点搞脑子的。大家能够细致思考思考。

源代码:

你可能感兴趣的文章
聚合(根)、实体、值对象精炼思考总结
查看>>
Aop RealProxy 千年遇BUG
查看>>
java解析虾米音乐
查看>>
rails将类常量重构到数据库对应的表中之三
查看>>
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
查看>>
mysql 多行合并函数
查看>>
【案例】RAID卡写策略改变引发的问题
查看>>
[Django学习]如何得到一个App
查看>>
sparkStreaming+sql点击前十商品
查看>>
第四十八讲:tapestry 与 淘宝kissy editor编辑器带图片上传
查看>>
图像处理入门——扭曲
查看>>
列表,元组,字典的异同
查看>>
在MyEclipse中构建SQL查询语句
查看>>
Linux/Centos 重置Mysql root用户密码
查看>>
2017-10-9linux文本处理
查看>>
CALayer的那些事(二)
查看>>
[C语言]unicode与utf-8编码转换(一)
查看>>
root用户可以引入cx_Oracle包,其他用户不可以导入
查看>>
Linux防火墙iptables学习笔记(二)参数指令
查看>>
Prometheus监控的最佳实践——关于监控的3项关键指标
查看>>