ProgressWheel是git是一个开源项目,为开发者提供一个扁平化的ProgressBar,并可对其进行深度定制

 
1,将ProgressWheel的源码拷贝到项目中
public class ProgressWheel extends View  
{  
    // Sizes (with defaults)  
    private int layout_height = 0;  
    private int layout_width = 0;  
    private int fullRadius = 100;  
    private int circleRadius = 80;  
    private int barLength = 60;  
    private int barWidth = 20;  
    private int rimWidth = 20;  
    private int textSize = 20;  
    private float contourSize = 0;  
    // Padding (with defaults)  
    private int paddingTop = 5;  
    private int paddingBottom = 5;  
    private int paddingLeft = 5;  
    private int paddingRight = 5;  
    // Colors (with defaults)  
    private int barColor = 0xAA000000;  
    private int contourColor = 0xAA000000;  
    private int circleColor = 0x00000000;  
    private int rimColor = 0xAADDDDDD;  
    private int textColor = 0xFF000000;  
    // Paints  
    private Paint barPaint = new Paint();  
    private Paint circlePaint = new Paint();  
    private Paint rimPaint = new Paint();  
    private Paint textPaint = new Paint();  
    private Paint contourPaint = new Paint();  
    // Rectangles  
    @SuppressWarnings("unused")  
    private RectF rectBounds = new RectF();  
    private RectF circleBounds = new RectF();  
    private RectF circleOuterContour = new RectF();  
    private RectF circleInnerContour = new RectF();  
    // Animation  
    // The amount of pixels to move the bar by on each draw  
    private int spinSpeed = 2;  
    // The number of milliseconds to wait inbetween each draw  
    private int delayMillis = 0;  
    private Handler spinHandler = new Handler()  
    {  
        /** 
         * This is the code that will increment the progress variable and so 
         * spin the wheel 
         */  
        @Override  
        public void handleMessage(Message msg)  
        {  
            invalidate();  
            if (isSpinning)  
            {  
                progress += spinSpeed;  
                if (progress > 360)  
                {  
                    progress = 0;  
                }  
                spinHandler.sendEmptyMessageDelayed(0, delayMillis);  
            }  
            // super.handleMessage(msg);  
        }  
    };  
    int progress = 0;  
    boolean isSpinning = false;  
    // Other  
    private String text = "";  
    private String[] splitText =  
    {};  
    /** 
     * The constructor for the ProgressWheel 
     *  
     * @param context 
     * @param attrs 
     */  
    public ProgressWheel(Context context, AttributeSet attrs)  
    {  
        super(context, attrs);  
        parseAttributes(context.obtainStyledAttributes(attrs,  
                R.styleable.ProgressWheel));  
    }  
    // ----------------------------------  
    // Setting up stuff  
    // ----------------------------------  
    /* 
     * When this is called, make the view square. From: 
     * http://www.jayway.com/2012 
     * /12/12/creating-custom-android-views-part-4-measuring 
     * -and-how-to-force-a-view-to-be-square/ 
     */  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
    {  
        // The first thing that happen is that we call the superclass  
        // implementation of onMeasure. The reason for that is that measuring  
        // can be quite a complex process and calling the super method is a  
        // convenient way to get most of this complexity handled.  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
        // We can’t use getWidth() or getHight() here. During the measuring  
        // pass the view has not gotten its final size yet (this happens first  
        // at the start of the layout pass) so we have to use getMeasuredWidth()  
        // and getMeasuredHeight().  
        int size = 0;  
        int width = getMeasuredWidth();  
        int height = getMeasuredHeight();  
        int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();  
        int heigthWithoutPadding = height - getPaddingTop()  
                - getPaddingBottom();  
        // Finally we have some simple logic that calculates the size of the  
        // view  
        // and calls setMeasuredDimension() to set that size.  
        // Before we compare the width and height of the view, we remove the  
        // padding,  
        // and when we set the dimension we add it back again. Now the actual  
        // content  
        // of the view will be square, but, depending on the padding, the total  
        // dimensions  
        // of the view might not be.  
        if (widthWithoutPadding > heigthWithoutPadding)  
        {  
            size = heigthWithoutPadding;  
        } else  
        {  
            size = widthWithoutPadding;  
        }  
        // If you override onMeasure() you have to call setMeasuredDimension().  
        // This is how you report back the measured size. If you don’t call  
        // setMeasuredDimension() the parent will throw an exception and your  
        // application will crash.  
        // We are calling the onMeasure() method of the superclass so we don’t  
        // actually need to call setMeasuredDimension() since that takes care  
        // of that. However, the purpose with overriding onMeasure() was to  
        // change the default behaviour and to do that we need to call  
        // setMeasuredDimension() with our own values.  
        setMeasuredDimension(size + getPaddingLeft() + getPaddingRight(), size  
                + getPaddingTop() + getPaddingBottom());  
    }  
    /** 
     * Use onSizeChanged instead of onAttachedToWindow to get the dimensions of 
     * the view, because this method is called after measuring the dimensions of 
     * MATCH_PARENT & WRAP_CONTENT. Use this dimensions to setup the bounds and 
     * paints. 
     */  
    @Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh)  
    {  
        super.onSizeChanged(w, h, oldw, oldh);  
        // Share the dimensions  
        layout_width = w;  
        layout_height = h;  
        setupBounds();  
        setupPaints();  
        invalidate();  
    }  
    /** 
     * Set the properties of the paints we're using to draw the progress wheel 
     */  
    private void setupPaints()  
    {  
        barPaint.setColor(barColor);  
        barPaint.setAntiAlias(true);  
        barPaint.setStyle(Style.STROKE);  
        barPaint.setStrokeWidth(barWidth);  
        rimPaint.setColor(rimColor);  
        rimPaint.setAntiAlias(true);  
        rimPaint.setStyle(Style.STROKE);  
        rimPaint.setStrokeWidth(rimWidth);  
        circlePaint.setColor(circleColor);  
        circlePaint.setAntiAlias(true);  
        circlePaint.setStyle(Style.FILL);  
        textPaint.setColor(textColor);  
        textPaint.setStyle(Style.FILL);  
        textPaint.setAntiAlias(true);  
        textPaint.setTextSize(textSize);  
        contourPaint.setColor(contourColor);  
        contourPaint.setAntiAlias(true);  
        contourPaint.setStyle(Style.STROKE);  
        contourPaint.setStrokeWidth(contourSize);  
    }  
    /** 
     * Set the bounds of the component 
     */  
    private void setupBounds()  
    {  
        // Width should equal to Height, find the min value to steup the circle  
        int minValue = Math.min(layout_width, layout_height);  
        // Calc the Offset if needed  
        int xOffset = layout_width - minValue;  
        int yOffset = layout_height - minValue;  
        // Add the offset  
        paddingTop = this.getPaddingTop() + (yOffset / 2);  
        paddingBottom = this.getPaddingBottom() + (yOffset / 2);  
        paddingLeft = this.getPaddingLeft() + (xOffset / 2);  
        paddingRight = this.getPaddingRight() + (xOffset / 2);  
        int width = getWidth(); // this.getLayoutParams().width;  
        int height = getHeight(); // this.getLayoutParams().height;  
        rectBounds = new RectF(paddingLeft, paddingTop, width - paddingRight,  
                height - paddingBottom);  
        circleBounds = new RectF(paddingLeft + barWidth, paddingTop + barWidth,  
                width - paddingRight - barWidth, height - paddingBottom  
                        - barWidth);  
        circleInnerContour = new RectF(circleBounds.left + (rimWidth / 2.0f)  
                + (contourSize / 2.0f), circleBounds.top + (rimWidth / 2.0f)  
                + (contourSize / 2.0f), circleBounds.right - (rimWidth / 2.0f)  
                - (contourSize / 2.0f), circleBounds.bottom - (rimWidth / 2.0f)  
                - (contourSize / 2.0f));  
        circleOuterContour = new RectF(circleBounds.left - (rimWidth / 2.0f)  
                - (contourSize / 2.0f), circleBounds.top - (rimWidth / 2.0f)  
                - (contourSize / 2.0f), circleBounds.right + (rimWidth / 2.0f)  
                + (contourSize / 2.0f), circleBounds.bottom + (rimWidth / 2.0f)  
                + (contourSize / 2.0f));  
        fullRadius = (width - paddingRight - barWidth) / 2;  
        circleRadius = (fullRadius - barWidth) + 1;  
    }  
    /** 
     * Parse the attributes passed to the view from the XML 
     *  
     * @param a 
     *            the attributes to parse 
     */  
    private void parseAttributes(TypedArray a)  
    {  
        barWidth = (int) a.getDimension(R.styleable.ProgressWheel_barWidth,  
                barWidth);  
        rimWidth = (int) a.getDimension(R.styleable.ProgressWheel_rimWidth,  
                rimWidth);  
        spinSpeed = (int) a.getDimension(R.styleable.ProgressWheel_spinSpeed,  
                spinSpeed);  
        delayMillis = a.getInteger(R.styleable.ProgressWheel_delayMillis,  
                delayMillis);  
        if (delayMillis < 0)  
        {  
            delayMillis = 0;  
        }  
        barColor = a.getColor(R.styleable.ProgressWheel_barColor, barColor);  
        barLength = (int) a.getDimension(R.styleable.ProgressWheel_barLength,  
                barLength);  
        textSize = (int) a.getDimension(R.styleable.ProgressWheel_textSize,  
                textSize);  
        textColor = (int) a.getColor(R.styleable.ProgressWheel_textColor,  
                textColor);  
        // if the text is empty , so ignore it  
        if (a.hasValue(R.styleable.ProgressWheel_text))  
        {  
            setText(a.getString(R.styleable.ProgressWheel_text));  
        }  
        rimColor = (int) a.getColor(R.styleable.ProgressWheel_rimColor,  
                rimColor);  
        circleColor = (int) a.getColor(R.styleable.ProgressWheel_circleColor,  
                circleColor);  
        contourColor = a.getColor(R.styleable.ProgressWheel_contourColor,  
                contourColor);  
        contourSize = a.getDimension(R.styleable.ProgressWheel_contourSize,  
                contourSize);  
        // Recycle  
        a.recycle();  
    }  
    // ----------------------------------  
    // Animation stuff  
    // ----------------------------------  
    protected void onDraw(Canvas canvas)  
    {  
        super.onDraw(canvas);  
        // Draw the inner circle  
        canvas.drawArc(circleBounds, 360, 360, false, circlePaint);  
        // Draw the rim  
        canvas.drawArc(circleBounds, 360, 360, false, rimPaint);  
        canvas.drawArc(circleOuterContour, 360, 360, false, contourPaint);  
        canvas.drawArc(circleInnerContour, 360, 360, false, contourPaint);  
        // Draw the bar  
        if (isSpinning)  
        {  
            canvas.drawArc(circleBounds, progress - 90, barLength, false,  
                    barPaint);  
        } else  
        {  
            canvas.drawArc(circleBounds, -90, progress, false, barPaint);  
        }  
        // Draw the text (attempts to center it horizontally and vertically)  
        float textHeight = textPaint.descent() - textPaint.ascent();  
        float verticalTextOffset = (textHeight / 2) - textPaint.descent();  
        for (String s : splitText)  
        {  
            float horizontalTextOffset = textPaint.measureText(s) / 2;  
            canvas.drawText(s, this.getWidth() / 2 - horizontalTextOffset,  
                    this.getHeight() / 2 + verticalTextOffset, textPaint);  
        }  
    }  
    /** 
     * Check if the wheel is currently spinning 
     */  
    public boolean isSpinning()  
    {  
        if (isSpinning)  
        {  
            return true;  
        } else  
        {  
            return false;  
        }  
    }  
    /** 
     * Reset the count (in increment mode) 
     */  
    public void resetCount()  
    {  
        progress = 0;  
        setText("0%");  
        invalidate();  
    }  
    /** 
     * Turn off spin mode 
     */  
    public void stopSpinning()  
    {  
        isSpinning = false;  
        progress = 0;  
        spinHandler.removeMessages(0);  
    }  
    /** 
     * Puts the view on spin mode 
     */  
    public void spin()  
    {  
        isSpinning = true;  
        spinHandler.sendEmptyMessage(0);  
    }  
    /** 
     * Increment the progress by 1 (of 360) 
     */  
    public void incrementProgress()  
    {  
        isSpinning = false;  
        progress += 20;  
        if (progress > 360)  
            progress = 0;  
        // setText(Math.round(((float) progress / 360) * 100) + "%");  
        spinHandler.sendEmptyMessage(0);  
    }  
    /** 
     * Set the progress to a specific value 
     */  
    public void setProgress(int i)  
    {  
        isSpinning = false;  
        progress = i;  
        spinHandler.sendEmptyMessage(0);  
    }  
    // ----------------------------------  
    // Getters + setters  
    // ----------------------------------  
    /** 
     * Set the text in the progress bar Doesn't invalidate the view 
     *  
     * @param text 
     *            the text to show ('\n' constitutes a new line) 
     */  
    public void setText(String text)  
    {  
        this.text = text;  
        splitText = this.text.split("\n");  
    }  
    public int getCircleRadius()  
    {  
        return circleRadius;  
    }  
    public void setCircleRadius(int circleRadius)  
    {  
        this.circleRadius = circleRadius;  
    }  
    public int getBarLength()  
    {  
        return barLength;  
    }  
    public void setBarLength(int barLength)  
    {  
        this.barLength = barLength;  
    }  
    public int getBarWidth()  
    {  
        return barWidth;  
    }  
    public void setBarWidth(int barWidth)  
    {  
        this.barWidth = barWidth;  
    }  
    public int getTextSize()  
    {  
        return textSize;  
    }  
    public void setTextSize(int textSize)  
    {  
        this.textSize = textSize;  
    }  
    public int getPaddingTop()  
    {  
        return paddingTop;  
    }  
    public void setPaddingTop(int paddingTop)  
    {  
        this.paddingTop = paddingTop;  
    }  
    public int getPaddingBottom()  
    {  
        return paddingBottom;  
    }  
    public void setPaddingBottom(int paddingBottom)  
    {  
        this.paddingBottom = paddingBottom;  
    }  
    public int getPaddingLeft()  
    {  
        return paddingLeft;  
    }  
    public void setPaddingLeft(int paddingLeft)  
    {  
        this.paddingLeft = paddingLeft;  
    }  
    public int getPaddingRight()  
    {  
        return paddingRight;  
    }  
    public void setPaddingRight(int paddingRight)  
    {  
        this.paddingRight = paddingRight;  
    }  
    public int getBarColor()  
    {  
        return barColor;  
    }  
    public void setBarColor(int barColor)  
    {  
        this.barColor = barColor;  
    }  
    public int getCircleColor()  
    {  
        return circleColor;  
    }  
    public void setCircleColor(int circleColor)  
    {  
        this.circleColor = circleColor;  
    }  
    public int getRimColor()  
    {  
        return rimColor;  
    }  
    public void setRimColor(int rimColor)  
    {  
        this.rimColor = rimColor;  
    }  
    public Shader getRimShader()  
    {  
        return rimPaint.getShader();  
    }  
    public void setRimShader(Shader shader)  
    {  
        this.rimPaint.setShader(shader);  
    }  
    public int getTextColor()  
    {  
        return textColor;  
    }  
    public void setTextColor(int textColor)  
    {  
        this.textColor = textColor;  
    }  
    public int getSpinSpeed()  
    {  
        return spinSpeed;  
    }  
    public void setSpinSpeed(int spinSpeed)  
    {  
        this.spinSpeed = spinSpeed;  
    }  
    public int getRimWidth()  
    {  
        return rimWidth;  
    }  
    public void setRimWidth(int rimWidth)  
    {  
        this.rimWidth = rimWidth;  
    }  
    public int getDelayMillis()  
    {  
        return delayMillis;  
    }  
    public void setDelayMillis(int delayMillis)  
    {  
        this.delayMillis = delayMillis;  
    }  
}  
 
2.将如下的属性拷贝到attrs.xml中
<?xml version="1.0" encoding="utf-8"?>  
<resources>  
    <declare-styleable name="ProgressWheel">  
        <attr name="text" format="string" />  
        <attr name="textColor" format="color" />  
        <attr name="textSize" format="dimension" />  
        <attr name="barColor" format="color" /><!-- 进度条颜色 -->  
        <attr name="rimColor" format="color" /><!-- 默认轮廓颜色 -->  
        <attr name="rimWidth" format="dimension" />  
        <attr name="spinSpeed" format="dimension" />  
        <attr name="delayMillis" format="integer" />  
        <attr name="circleColor" format="color" /><!-- 圆圈内部的颜色 -->  
        <attr name="radius" format="dimension" />  
        <attr name="barWidth" format="dimension" /><!-- 进度条宽度 -->  
        <attr name="barLength" format="dimension" /><!-- 进度条长度(即进度条走过的长度) -->  
        <attr name="contourColor" format="color"/><!-- 控制外边缘颜色 -->  
        <attr name="contourSize" format="dimension"/>  
    </declare-styleable>     
</resources>  
 
3,在布局文件中声明空间
 
4,声明控件
<com.example.myprogresswheel.ProgressWheel
        android:id="@+id/pw_spinner"  
        android:layout_width="180dp"  
        android:layout_height="180dp"  
        android:layout_centerInParent="true"  
        ProgressWheel:barColor="#0097D6"  
        ProgressWheel:barLength="160dp"  
        ProgressWheel:barWidth="15dp"  
        ProgressWheel:rimColor="#330097D6"  
        ProgressWheel:rimWidth="15dp"  
        ProgressWheel:text="wait..."  
        ProgressWheel:contourColor="#330097D6"  
        ProgressWheel:textColor="#222" ></com.example.myprogresswheel.ProgressWheel>
 
5,在代码中使用控件
        ProgressWheel wheel=(ProgressWheel) findViewById(R.id.pw_spinner);
        wheel.spin();//使控件开始旋转  
 
        wheel.setProgress(180);//设置进度
        wheel.incrementProgress();//增加进度
        wheel.spin();//开始旋转
        wheel.stopSpinning();//停止旋转
 
 

android扁平化ProgressBar--progressWheel的更多相关文章

  1. Android 扁平化button

    View 创建 colors.xml 文件定义两个颜色 1. <resources> 2.     <color name="blue_pressed">@ ...

  2. [转 载] android 谷歌 新控件(约束控件 )ConstraintLayout 扁平化布局

    序 在Google IO大会中不仅仅带来了Android Studio 2.2预览版,同时带给我们一个依赖约束的库. 简单来说,她是相对布局的升级版本,但是区别与相对布局更加强调约束.何为约束,即控件 ...

  3. Android自定义扁平化对话框

    平时我们开发的大多数的Android.iOS的APP,它们的风格都是拟物化设计.如今Android 4.X.iOS 7.WP8采用的是扁平化设计,可以看出扁平化设计是未来UI设计的趋势.其实扁平化设计 ...

  4. android 自己定义标签的使用,实现扁平化UI设计

    2014年8月6日11:06:44 android对自己定义标签的使用.实现扁平化UI设计: 1.attrs.xml文件里自己定义标签 如: <?xml version="1.0&qu ...

  5. C# winform 界面美化技巧(扁平化设计)

    关于C#界面美化的一些小技巧 在不使用第三方控件如 IrisSkin 的前提下,依然可以对winform做出让人眼前一亮的美化 首先,我们先来实现主界面的扁平化 此处分为两个步骤,第一步是更改winf ...

  6. 怎样做出优秀的扁平化设计风格 PPT 或 Keynote 幻灯片演示文稿?(装)

    不知道你有没有想过,为什么很人多的扁平化 PPT 是这个样子: 或者是这样: 然而,还有一小撮人的扁平化 PPT 却拥有那么高颜值: 为什么会产生这么大的差距呢?丑逼 PPT 应该如何逆袭成为帅逼呢? ...

  7. Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果

    Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果 分享下我项目中用到的几种Button的效果,说实话,还真挺好看的 一.标准圆角 效果是这样的 他的实现很简单,我们只需要两个 ...

  8. Html5和Css3扁平化风格网页

    前言 扁平化概念的核心意义 去除冗余.厚重和繁杂的装饰效果.而具体表现在去掉了多余的透视.纹理.渐变以及能做出3D效果的元素,这样可以让“信息”本身重新作为核心被凸显出来.同时在设计元素上,则强调了抽 ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(50)-Easyui 扁平化皮肤

    最近抽了点时间仿做了点皮肤,只供欣赏!扁平化

随机推荐

  1. 小白袍 -- Chapter 1.1 避不开的编解码

    1.1  避不开的编解码 能阅读本文的想开都是从事计算机开发工作的,那么弱弱的问自己一下,有没有受到过编码的纠缠呢?有没有动过心思,如果没有编码该多好? 1.1.1  这个翻译你得捏着鼻子用 要想说明 ...

  2. ios应用数据存储方式(偏好设置)-转

    一.简单介绍 1.很多ios应用都支持偏好设置,比如保存用户名,密码,字体大小等设置,ios提供了一套标准的解决方案来为应用加入偏好设置功能. 2.每个应用都有个NSUserDefaults实例,通过 ...

  3. LeetCode 中级 - 从前序与中序遍历序列构造二叉树(105)

    一个前序遍历序列和一个中序遍历序列可以确定一颗唯一的二叉树. 根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root),  然后在中 ...

  4. SPOJ PRIME1 - Prime Generator(线性筛)

    Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate ...

  5. 分页离线条件查询 页面响应500 后端未报异常 list集合有数据

    如果 使用同一个Hibernate的DetachedCriteria离线条件查询对象同时查询“过滤后条数” 和 “过滤后的数据集合”,那么查询记录数时需要设置聚合函数条件并且 使用聚合函数  代码要在 ...

  6. MySQL必会

    SQL语言对大小写不敏感,但一般使用大.1.创建数据库 CREATE DATABASE test; 2.授予权限 CRANT ALL ON test.* to user(s); 3.使用指定数据库 U ...

  7. Hadoop(25)-高可用集群配置,HDFS-HA和YARN-HA

    一. HA概述 1. 所谓HA(High Available),即高可用(7*24小时不中断服务). 2. 实现高可用最关键的策略是消除单点故障.HA严格来说应该分成各个组件的HA机制:HDFS的HA ...

  8. Hadoop(19)-MapReduce框架原理-Combiner合并

    1. Combiner概述 2. 自定义Combiner实现步骤 1). 定义一个Combiner继承Reducer,重写reduce方法 public class WordcountCombiner ...

  9. poj_2339

    参考:https://blog.csdn.net/yzl_rex/article/details/7600906 https://blog.csdn.net/acm_JL/article/detail ...

  10. python2.7练习小例子(十三)

        13):题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5.     程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成.(1)如果这个质数恰等于 ...