美文网首页
自定义View--带百分比圆型进度条

自定义View--带百分比圆型进度条

作者: MinicupSimon | 来源:发表于2017-12-28 09:36 被阅读0次

    先上效果图

    progressbar.gif

    知识点

    1. Canvas简单操作

    2. 阴影效果的实现

    3. 动画效果的实现

    个人觉得,像这样比较简单的控件,并且使用场合不多的情况下,无须按照标准的自定义View的步骤来, 我指的是在attr.xml中定义并声明属性,然后再从控件中获取TypedArray。不光写起来麻烦,而且引用也麻烦
    将下面代码直接Copy到项目中,AS会将包名也改掉,一步到位。再根据自己的需求,简单修改即可。
    package com.minicup.custom.progressbar;
    
    import android.animation.ValueAnimator;
    import android.content.Context;
    import android.graphics.BlurMaskFilter;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.graphics.Typeface;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.animation.DecelerateInterpolator;
    
    
    /**
     * Created by gy on 2017/12/27.
     */
    
    public class CircleView extends View {
    
        /**
         * 中间圆及进度条颜色
         */
        private String mReachColor = "#54c484";
    
        /**
         * 默认外环背景颜色
         */
        private String mDefaultColor = "#dddddd";
    
        private Paint mCenterPaint;
        private Paint mRingPaint;
        private Paint mTextPaint;
    
        /**
         * ACTION_UP时的阴影
         */
        private BlurMaskFilter maskfilterUp;
    
        /**
         * ACTION_DOWN时的阴影
         */
        private BlurMaskFilter maskfilterDown;
    
        private RectF ringRect;
        /**
         * 外环宽度
         */
        private int mRingWidth = dp2px(10);
        /**
         * 阴影大小
         */
        private int mShadowRadius = dp2px(5);
    
        /**
         * 控件的大小
         */
        private int mViewRadius = dp2px(100);
    
        /**
         * 起使角度
         */
        private float startAngle = 0;
    
        /**
         * 终止角度
         */
        private float endAngle = 0;
    
        /**
         * 动画时,当前的角度
         */
        private float currentAngle;
    
        /**
         * 中央文字
         */
        private String mPercentage = "";
    
        /**
         * 字体大小
         */
        private int mTextSize = 30;
        private ValueAnimator anim;
    
        /**
         * 动画时,当前的百分比
         */
        private int p;
    
        public CircleView(Context context) {
            super(context, null);
        }
    
        public CircleView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            setLayerType(LAYER_TYPE_SOFTWARE, null);
    
            mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            maskfilterUp = new BlurMaskFilter(mShadowRadius, BlurMaskFilter.Blur.SOLID);
            maskfilterDown = new BlurMaskFilter(mShadowRadius*2, BlurMaskFilter.Blur.SOLID);
            mCenterPaint.setMaskFilter(maskfilterUp);
            mCenterPaint.setColor(Color.parseColor(mReachColor));
    
            mRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mRingPaint.setColor(Color.parseColor(mDefaultColor));
            mRingPaint.setStrokeCap(Paint.Cap.ROUND);
            mRingPaint.setStrokeWidth(mRingWidth);
            mRingPaint.setStyle(Paint.Style.STROKE);
    
            mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mTextPaint.setColor(Color.WHITE);
            mTextPaint.setTextSize(spTopx(mTextSize));
            mTextPaint.setTypeface(Typeface.SANS_SERIF);
    
            //这里应该在Activity中设置
            setPercentage(70);
        }
    
    
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            ringRect = new RectF(mRingWidth/2, mRingWidth/2, w-mRingWidth/2, w-mRingWidth/2);
            super.onSizeChanged(w, h, oldw, oldh);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(mViewRadius*2, mViewRadius*2);
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            int radius = mViewRadius;
            //中央圆
            canvas.drawCircle(radius, radius, radius * 0.8f, mCenterPaint);
    
            //外环背景
            mRingPaint.setColor(Color.parseColor(mDefaultColor));
            canvas.drawCircle(radius, radius, radius-mRingWidth/2, mRingPaint);
            //外环进度
            mRingPaint.setColor(Color.parseColor(mReachColor));
            canvas.drawArc(ringRect, startAngle, currentAngle, false, mRingPaint);
    
            //中央文字
            Rect rect = new Rect();
            mTextPaint.getTextBounds(mPercentage, 0, mPercentage.length(), rect);
            canvas.drawText(mPercentage, 0, mPercentage.length(), radius-rect.width()/2, radius+rect.height()/2, mTextPaint);
    
            super.onDraw(canvas);
        }
    
        public int dp2px(int dp){
            return ((int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()) + 0.5));
        }
    
        private float spTopx(int sp) {
            return ((int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics()) + 0.5));
    
        }
    
    
        /**
         * 用以实现点击效果
         * @param event
         * @return
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int actionMasked = event.getActionMasked();
            if(actionMasked==MotionEvent.ACTION_DOWN){
                mCenterPaint.setMaskFilter(maskfilterDown);
                startAnimation();
                postInvalidate();
            }else if(actionMasked==MotionEvent.ACTION_UP){
                mCenterPaint.setMaskFilter(maskfilterUp);
                postInvalidate();
            }
            return true;
        }
    
    
        public void setPercentage(int p) {
            endAngle = 360 * p / 100;
            this.p = p;
            mPercentage = String.format("%s%%", p);
            startAnimation();
        }
    
    
        public void startAnimation(){
            anim = ValueAnimator.ofFloat(startAngle, endAngle);
            anim.setInterpolator(new DecelerateInterpolator(1.1f));
            anim.setDuration(1000);
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    currentAngle = (Float) animation.getAnimatedValue();
                    mPercentage = String.format("%s%%", ((int) (p * currentAngle / endAngle)));
                    postInvalidate();
                }
            });
            anim.start();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:自定义View--带百分比圆型进度条

          本文链接:https://www.haomeiwen.com/subject/ixrmgxtx.html