zoukankan      html  css  js  c++  java
  • android扁平化ProgressBar--progressWheel

    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 (' ' constitutes a new line) 
         */  
        public void setText(String text)  
        {  
            this.text = text;  
            splitText = this.text.split(" ");  
        }  
        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();//停止旋转
     
     





    qq3061280@163.com
  • 相关阅读:
    第二章 Google guava cache源码解析1--构建缓存器
    第十一章 AtomicInteger源码解析
    JVM虚拟机(五):JDK8内存模型—消失的PermGen
    JVM虚拟机(四):JVM 垃圾回收机制概念及其算法
    Java中RunTime类介绍
    JVM虚拟机(三):参数配置
    ZooKeeperEclipse 插件
    zookeeper(五):Zookeeper中的Access Control(ACL)
    zookeeper(六):Zookeeper客户端Curator的API使用详解
    Java并发编程(九):拓展
  • 原文地址:https://www.cnblogs.com/aibuli/p/3f13bd9bad34cfa289c62e18c30d00cb.html
Copyright © 2011-2022 走看看