Android MaterialProgressDrawable类

来源:互联网 发布:数据分析是什么工作 编辑:程序博客网 时间:2024/06/08 14:37

一:常用方法

返回值 方法和描述 void updateSizes(int size)
设置大小,可以选LARGE、DEFAULT void showArrow(boolean show)
设置是否显示箭头 void setArrowScale(float scale)
设置箭头缩放大小,0f~1f void setStartEndTrim(float startAngle, float endAngle)
设置进度条的开始和结尾,也就是长度,范围0f~1f,比如setStartEndTrim(0f,0.8f) void setProgressRotation(float rotation)
设置旋转角度,0f~1f void setBackgroundColor(int color)
设置背景颜色 void setColorSchemeColors(int… colors)
设置进度条的颜色,可以是多种颜色,转一圈换一个 void setAlpha(int alpha)
设置透明度,0-255,注意:默认一开始透明度是0 void start()
开始转圈动画 void stop()
终止进行中的动画,并且将进度条长度归零 int getAlpha()
获取当前透明度 int getIntrinsicHeight()
获取Drawable高度 int getIntrinsicWidth()
获取Drawable宽度

二:使用

从v4包复制MaterialProgressDrawable类,改为public class

初始化

    private final int CIRCLE_BG_LIGHT = 0xFFFAFAFA;//背景颜色十六进制值    public void init() {        //parent是mImageView的父布局,用于启动动画,不能为null        mProgress = new MaterialProgressDrawable(this, parent);        mProgress.setBackgroundColor(CIRCLE_BG_LIGHT);        mProgress.setColorSchemeColors(colors);        mImageView.setImageDrawable(mProgress);    }

注意: setBackgroundColor和setColorSchemeColors设置的颜色值不能之间使用R.color.xx,可以使用颜色的十六进制,如0xFFFAFAFA,或者 getResources().getColor(R.color.xx)转换成十六进制

启动:

    mProgress.setAlpha(255);    mProgress.setStartEndTrim(0f, 0.8f);    mProgress.setArrowScale(1f); //0~1之间    mProgress.setProgressRotation(1);    mProgress.showArrow(true);    mProgress.start();

停止

    mProgress.stop();

三:源码

设置ring的基本参数,根据Density转换成px,适配各种分辨率

    //设置各个参数,使用updateSizes()方法修改样式DEFAULT和LARGE    private void setSizeParameters(double progressCircleWidth, double progressCircleHeight,            double centerRadius, double strokeWidth, float arrowWidth, float arrowHeight) {        final Ring ring = mRing;        final DisplayMetrics metrics = mResources.getDisplayMetrics();        final float screenDensity = metrics.density;//获取屏幕密度        //设置各个参数,乘以screenDensity为了从dp转为px        mWidth = progressCircleWidth * screenDensity;        mHeight = progressCircleHeight * screenDensity;        ring.setStrokeWidth((float) strokeWidth * screenDensity);        ring.setCenterRadius(centerRadius * screenDensity);        ring.setColorIndex(0);        ring.setArrowDimensions(arrowWidth * screenDensity, arrowHeight * screenDensity);        ring.setInsets((int) mWidth, (int) mHeight);    }

主要的绘制工作都在ring中

         /**         * Draw the progress spinner         */        public void draw(Canvas c, Rect bounds) {            final RectF arcBounds = mTempBounds;            arcBounds.set(bounds);            arcBounds.inset(mStrokeInset, mStrokeInset);            final float startAngle = (mStartTrim + mRotation) * 360;            final float endAngle = (mEndTrim + mRotation) * 360;            float sweepAngle = endAngle - startAngle;            mPaint.setColor(mCurrentColor);            //绘制弧线            c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);            //绘制三角形            drawTriangle(c, startAngle, sweepAngle, bounds);            //当透明度小于255,透明度值和弧线三角形正好相反            if (mAlpha < 255) {                mCirclePaint.setColor(mBackgroundColor);                mCirclePaint.setAlpha(255 - mAlpha);                c.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), bounds.width() / 2,                        mCirclePaint);            }        }

动画:

    //设置动画    private void setupAnimators() {        final Ring ring = mRing;        final Animation animation = new Animation() {            //第一个参数为动画的进度时间值,取值范围为[0.0f,1.0f],第二个参数Transformation记录着动画某一帧中变形的原始数据。该方法在动画的每一帧显示过程中都会被调用。                @Override            public void applyTransformation(float interpolatedTime, Transformation t) {            //只在start方法中,起始角度和终止角度不一样时设置为true,当第一次动画结束后设置为false                if (mFinishing) {                    applyFinishTranslation(interpolatedTime, ring);//设置ring的值和颜色                } else {                    // The minProgressArc is calculated from 0 to create an                    // angle that matches the stroke width.                    final float minProgressArc = getMinProgressArc(ring);                    final float startingEndTrim = ring.getStartingEndTrim();                    final float startingTrim = ring.getStartingStartTrim();                    final float startingRotation = ring.getStartingRotation();                    updateRingColor(interpolatedTime, ring);                    // Moving the start trim only occurs in the first 50% of a                    // single ring animation                    //前面半部分只设置起点的值                    if (interpolatedTime <= START_TRIM_DURATION_OFFSET) {                        // scale the interpolatedTime so that the full                        // transformation from 0 - 1 takes place in the                        // remaining time                        final float scaledTime = (interpolatedTime)                                / (1.0f - START_TRIM_DURATION_OFFSET);                        final float startTrim = startingTrim                                + ((MAX_PROGRESS_ARC - minProgressArc) * MATERIAL_INTERPOLATOR                                        .getInterpolation(scaledTime));                        ring.setStartTrim(startTrim);                    }                    // Moving the end trim starts after 50% of a single ring                    // animation completes                     // 后半部分只设置终点的值                    if (interpolatedTime > END_TRIM_START_DELAY_OFFSET) {                        // scale the interpolatedTime so that the full                        // transformation from 0 - 1 takes place in the                        // remaining time                        final float minArc = MAX_PROGRESS_ARC - minProgressArc;                        float scaledTime = (interpolatedTime - START_TRIM_DURATION_OFFSET)                                / (1.0f - START_TRIM_DURATION_OFFSET);                        final float endTrim = startingEndTrim                                + (minArc * MATERIAL_INTERPOLATOR.getInterpolation(scaledTime));                        ring.setEndTrim(endTrim);                    }                     //没看出来有什么作用。。                    final float rotation = startingRotation + (0.25f * interpolatedTime);                    ring.setRotation(rotation);                    //总角度为1080,分5圈转完                    // ((FULL_ROTATION / NUM_POINTS) * interpolatedTime) 当前动画需要转的角度                    //(FULL_ROTATION * (mRotationCount / NUM_POINTS)) 承接上一圈转的角度                    //如第一圈,角度从0~216,第二圈216~432...第五圈864~1080。在draw(canvas)中设置canvas角度旋转                    float groupRotation = ((FULL_ROTATION / NUM_POINTS) * interpolatedTime)                            + (FULL_ROTATION * (mRotationCount / NUM_POINTS));                    setRotation(groupRotation);//设置旋转的角度并更新,调用draw()                }            }        };        animation.setRepeatCount(Animation.INFINITE);        animation.setRepeatMode(Animation.RESTART);        animation.setInterpolator(LINEAR_INTERPOLATOR);        animation.setAnimationListener(new Animation.AnimationListener() {                @Override            public void onAnimationStart(Animation animation) {                mRotationCount = 0;            }                @Override            public void onAnimationEnd(Animation animation) {                // do nothing            }                @Override            public void onAnimationRepeat(Animation animation) {                //记录完成动画时的角度信息                ring.storeOriginals();                //下一个颜色                ring.goToNextColor();                ring.setStartTrim(ring.getEndTrim());                if (mFinishing) {                    //完成第一个动画,关闭箭头,SwipeRefreshLayout中向下拉完成后                    mFinishing = false;                    animation.setDuration(ANIMATION_DURATION);                    ring.setShowArrow(false);                } else {                    mRotationCount = (mRotationCount + 1) % (NUM_POINTS);                }            }        });        mAnimation = animation;    }

第一遍动画调用applyFinishTranslation完成,之后关闭箭头,开始新的动画,每次的动画是前50%只更改起点位置,后50%只更改终点位置,通过一系列的计算,旋转canvas
参考资料:http://blog.csdn.net/tyzlmjj/article/details/50557397

0 0
原创粉丝点击