美文网首页
自定义View之三-画笔(计步器效果)

自定义View之三-画笔(计步器效果)

作者: woochen123 | 来源:发表于2017-11-13 15:50 被阅读0次

    效果图

    step.gif

    1.自定义属性

        <declare-styleable name="StepView">
            <attr name="maxStep" format="integer"></attr>
            <attr name="currentStep" format="integer"/>
            <attr name="stepColor" format="color|reference"/>
            <attr name="outColor" format="color|reference"/>
            <attr name="innerColor" format="color|reference"/>
            <attr name="stepSize" format="dimension"/>
            <attr name="roundWidth" format="float"/>
        </declare-styleable>
    

    2.继承VIew

    
    /**
     *@author woochen123
     *@time 2017/11/13 15:39
     *@desc
     */
    
    public class StepView extends View {
        private static final String TAG = "StepView";
        //最大步数 默认1000
        private int mMaxStep = 100;
        //当前步数 默认500
        private int mCurrentStep = 50;
        //控件宽度
        private int mViewWidth;
        //空间高度
        private int mViewHeight;
        //圆环宽度
        private int mRoundWidth = 30;
        //起始角度
        private float mStartAngle = 135;
        //旋转角度
        private float mSweepAngle = 270;
        //步数文字大小 sp
        private int mTextSize = 15;
        //步数文字颜色
        private int mTextColor = Color.RED;
        //外层圆环颜色
        private int mOutColor = Color.BLUE;
        //内层圆环颜色
        private int mInnerColor = Color.RED;
    
    
        public StepView(Context context) {
            this(context, null);
        }
    
        public StepView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public StepView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //自定义属性
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StepView);
            mMaxStep = array.getInt(R.styleable.StepView_maxStep, mMaxStep);
            mRoundWidth = (int) array.getFloat(R.styleable.StepView_roundWidth, mRoundWidth);
            mCurrentStep = array.getInt(R.styleable.StepView_currentStep, mCurrentStep);
            mTextColor = array.getColor(R.styleable.StepView_stepColor, mTextColor);
            mOutColor = array.getColor(R.styleable.StepView_outColor, mOutColor);
            mInnerColor = array.getColor(R.styleable.StepView_innerColor, mInnerColor);
            mTextSize = array.getDimensionPixelSize(R.styleable.StepView_stepSize, sp2Px(mTextSize));
            array.recycle();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
            mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            if (heightMode == MeasureSpec.AT_MOST) {
                //如果是包裹内容
                mViewHeight = mViewWidth;
            }
            setMeasuredDimension(mViewWidth, mViewHeight);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //1.画背景圆弧
            int centerX = mViewWidth / 2;
            int centerY = mViewHeight / 2;
            //半径
            int radius = centerX - mRoundWidth;
            //矩形区域
            RectF oval = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
            Paint mPaint = new Paint();
            mPaint.setColor(mOutColor);
            //设置圆弧的宽度(设置空心线宽)
            mPaint.setStrokeWidth(mRoundWidth);
            //设置画笔的样式
            mPaint.setStyle(Paint.Style.STROKE);
            //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式 Cap.ROUND,或方形样式Cap.SQUARE
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            //设置结合处的形状,有三个选择:BEVEL、MITER、ROUND,分别表示直线、直角、圆角
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            //抗锯齿
            mPaint.setAntiAlias(true);
            //oval:圆弧所在的椭圆对象 startAngle:开始角度  水平向右是0°sweepAngle:旋转角度  useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示   panint:画笔
            canvas.drawArc(oval, mStartAngle, mSweepAngle, false, mPaint);
    
            //2.画进度圆弧
            mPaint.setColor(mInnerColor);
            float currentPercent = mCurrentStep * 1.0f / mMaxStep;
            canvas.drawArc(oval, mStartAngle, mSweepAngle * currentPercent, false, mPaint);
    
            //3.画步数文字
            //绘制文字
            String mStep = mCurrentStep + "";
            //重置画笔
            mPaint.reset();
            //无锯齿
            mPaint.setAntiAlias(true);
            //设置文字大小
            mPaint.setTextSize(mTextSize);
            //设置文字颜色
            mPaint.setColor(mTextColor);
            Log.e(TAG, "onDraw: "+mTextColor );
            //测量文字的宽高
            Rect textBounds = new Rect();
            mPaint.getTextBounds(mStep, 0, mStep.length(), textBounds);
            //计算文字的基线
            int dx = (getWidth() - textBounds.width()) / 2;
            Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
            float baseLine = getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2  - fontMetrics.bottom;
            //text:要绘制的内容 x:基线的横坐标 y:基线的纵坐标 paint:画笔
            canvas.drawText(mStep, dx, baseLine, mPaint);
        }
    
        private int sp2Px(int sp) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sp, getResources().getDisplayMetrics());
        }
    
        /**
         * 设置最大步数
         * @param maxStep
         */
        public void setMaxStep(int maxStep) {
            if(maxStep < 0 ){
             throw new IllegalArgumentException("max 不能小于0!");
            }
            this.mMaxStep = maxStep;
        }
    
        /**
         * 设置当前步数
         * @param currentStep
         */
        public void setCurrentStep(int currentStep) {
            if(currentStep < 0 ){
                throw new IllegalArgumentException("max 不能小于0!");
            }
            this.mCurrentStep = currentStep;
            invalidate();
        }
    }
    

    3.使用

        <com.example.admin.testapplication.views.step.StepView
            android:id="@+id/stepView"
            app:stepSize="50sp"
            app:stepColor="#00ff00"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
         final StepView stepView = (StepView) findViewById(R.id.stepView);
            stepView.setMaxStep(1000);
            ValueAnimator valueAnimator =ValueAnimator.ofInt(0,800);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    int value = (int) animation.getAnimatedValue();
                    stepView.setCurrentStep(value);
                }
            });
            valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
            valueAnimator.setDuration(1500);
            valueAnimator.start();
    

    相关文章

      网友评论

          本文标题:自定义View之三-画笔(计步器效果)

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