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

时间: 2024-08-07 00:14:05

Material Design学习之 ProgreesBar的相关文章

MATERIAL DESIGN学习笔记

一.核心思想 ,aterial design的核心思想,就是把物理世界的体验带进屏幕.去掉现实中的杂质和随机性,保留其最原始纯净的形态.空间关系.变化与过渡,配合虚拟世界的灵活特性,还原最贴近真实的体验,达到简洁与直观的效果. Material design是最重视跨平台体验的一套设计语言.由于规范严格细致,保证它在各个平台使用体验高度一致.不过目前还只有Google自家的服务这么做,毕竟其他平台有自己的规范与风格. 二.材质与空间 材质 Material design中,最重要的信息载体就是魔

Android Material Design学习之RecyclerView代替 ListView

前言 # Android Material Design越来越流行,以前很常用的 ListView 现在也用RecyclerView代替了,实现原理还是相似的.笔者实现一下 RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出. 源码地址(欢迎star) https://github.com/studychen/SeeNewsV2 本文链接 http://blog.csdn.net/never_cxb/article/details/50495505,转载请注明出处. 复习 L

Material Design学习之 Switch(详细解释)

转载请注明出处:王亟亟的大牛之路 继续这一系列的Material Design之行,昨天讲的是Sliders链接如下:http://blog.csdn.net/ddwhan0123/article/details/50586510 今天讲的是Switch,本来有考虑把它和CheckBox一起做了,但是毕竟实现不同,还是分开做吧,废话不多,开始正题 开关 On/off 开关切换单一设置选择的状态.开关控制的选项以及它的状态,应该明确的展示出来并且与内部的标签相一致.开关应该单选按钮呈现相同的视觉特

Material Design学习之 EditText (功能强大,优于系统自带,感谢“扔物线”)

转载请注明出处:王亟亟的大牛之路 继续之前的Material Design历程,今天是EditText,素材来源于http://www.rengwuxian.com/post/materialedittext(那么代码解释部分大家可以看原作者的文档,我在这里把理论知识灌输下就OK了,作者做的很全面,我都不知道要讲什么了 只能6666666) 大牛的这个库已经有了广泛的认知度和认可,EditText部分就拿他的作为比较推崇的演示版本. 因为大牛已经做了Jar包的支持,所以平时的拆的工作都省了,要直

Material Design学习之 Sliders(详细分析,悬空气球显示进度值,附带Eclipse可以jar)

转载请注明出处:王亟亟的大牛之路 Material Design系列的文章这是第五篇,今天讲滑块控件(Sliders). 之前的传送门:http://blog.csdn.net/ddwhan0123/article/details/50578348(代码实现都靠画,学好View还是很重要的) 老规矩,先说下理论部分 滑块控件(Sliders,简称滑块)可以让我们通过在连续或间断的区间内滑动锚点来选择一个合适的数值.区间最小值放在左边,对应的,最大值放在右边.滑块(Sliders)可以在滑动条的左

Material Design学习

Android 5.0 推出Material Design 同时推出的新的控件和布局有: RecyclerView CardView Paletee 参考:http://blog.csdn.net/feiduclear_up/article/details/46439005 ToolBar 参考:http://blog.csdn.net/feiduclear_up/article/details/46457433 FloatingActionButton TextInputLayout Snac

Android Material Design 学习笔记 - Matrial Theme

google在2014年 I/O大会上推出了一种新的设计设计语言—Material design,这种设计语言语言旨在为手机.平板电脑.台式机和“其他平台”提供更一致.更广泛的“外观和感觉”(附上官方链接:http://developer.android.com/training/material/index.html) 在以后的Android中,我觉得Design风格将逐渐流行,所以:为了跟着潮流,我们也是要不断的与时俱进 --->> 如何使用Design主题? 使用的时候,你仅仅需要在St

Material Design学习之 Dialog(顺便把前两天AppBarLayout没讲的部分提一提)

转载请注明出处:王亟亟的大牛之路 继续之前的MD系列的内容,今天说Dialog,不知道还能翻几篇,反正这一系列都说完了话就找点别的内容整整. Dialogs (提示框)用于提示用户作一些决定,或者是完成某个任务时需要的一些其它额外的信息. Dialog可以是用一种 取消/确定 的简单应答模式,也可以是自定义布局的复杂模式,比如说一些文本设置或者是文本输入 . 官方的呈现,像这样 Dialog 包含了一个标题(可选),内容 ,事件. 标题:主要是用于简单描述下选择类型.它是可选的,要需要的时候赋值

拥抱Material Design!你的世界里不应该只有Bootstrap

前言 当然这里谈论的是前端UI设计类框架,如果你打开了这篇文章,那你一定不会陌生bootstrap吧,如果你还没听过bootstrap,那就请你关闭了这个页面,当这个文章从来没存在过!如果你对Material Design一无所知或者不是很了解 ,强烈移步<material design学习笔记>这篇文章,超赞!看完你一定会爱上Material Design的!当然,同时他对我们前端的UI实现要求也更高了! 在2014年谷歌高调展示了他们最新的Material Design设计方案,一改往日“