zoukankan      html  css  js  c++  java
  • Material Design学习之 ProgreesBar

    转载奇怪注明出处:王亟亟的大牛之路

    继续我们Material Design的内容,这一篇讲的是进度条,上一篇是Switch地址例如以下:http://blog.csdn.net/ddwhan0123/article/details/50592579


    进度和动态

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

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

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

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

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

    线形进度指示器

    线形进度指示器应始终从 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圆弧增大缩小的无限循环计算绘画,计算这部分逻辑还是有点搞脑子的。大家能够细致思考思考。

    源代码:https://github.com/ddwhan0123/BlogSample/blob/master/MaterialDesignProgress.zip

  • 相关阅读:
    初探diskstats
    JVM参数简述
    304 Not Modified 简述
    vmstat命令
    iostat 工具分析I/O性能
    git添加公钥后报错sign_and_send_pubkey: signing failed: agent refused operation
    Mysql ibdata1简述
    Mysql 事务日志(Ib_logfile)
    django项目一:基于django2.2可重用登录与注册模块-前端页面配置
    django项目一:基于django2.2可重用登录与注册模块-url路由和视图
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7364301.html
Copyright © 2011-2022 走看看