前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android – 环形进度条

Android – 环形进度条

作者头像
code_horse
发布2018-07-02 11:27:06
1.2K0
发布2018-07-02 11:27:06
举报
文章被收录于专栏:Android NoteAndroid Note

环形进度条

ring_circle_progress.gif

如上图所示,之所以想到写这个,因为项目中有这样的需求,所以自己就去琢磨琢磨该怎么去实现这个需求。 实现思路: ① 画个圆弧 ② 圆弧上画个圆 ③ 画进度条 ④ 在圆弧的中心绘制进度值

好了,思路已经有了,我们现在一个一个来实现。

画个圆弧

canvas.drawArc(rectF, 45, 270, false, mRingPaint);

这样就画了一个我们需要的圆弧。

圆弧上画个圆 画圆就需要圆心和半径。半径比较好得到。这里就半径用到了点数学上的知识。

 float radius = (float) ((width - mArcDis - mArcDis) / 2);
 float pointX = (float) (mCircleX + radius * Math.cos(mSwipeAngle * 3.14 / 180));
 float pointY = (float) (mCircleY + radius * Math.sin(mSwipeAngle * 3.14 / 180));

画进度条 这里的进度条,就是重新绘制一个重合的圆弧

canvas.drawArc(rectF, 45, mSwipeAngle-45, false, mSwipePaint);

在圆弧的中心绘制进度值

float v = mTextPaint.measureText(String.valueOf((int) Math.floor((float) (mSwipeAngle - 45) / 270 * 100)));
canvas.drawText(String.valueOf((int)Math.floor((float)(mSwipeAngle-45)/270*100)),mCircleX-(int)v/2,mCircleY+Px2DpUtil.dp2px(getContext(),10),mTextPaint);
canvas.drawText("%",mCircleX+(int)v/2,mCircleY+Px2DpUtil.dp2px(getContext(),10),mPercentPaint);

下面给出全部代码以供参考:

public class CircleRingView extends View {
    private int mArcDis;
    private Paint mRingPaint;
    private Paint mPointPaint;
    private int mPointAngle;
    private float mCircleX;
    private float mCircleY;
    private int mSwipeAngle=45;

    private Handler mHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mSwipeAngle == mPointAngle) {
                mHandler.removeMessages(0);
            }else {
                ++mSwipeAngle;
                postInvalidate();
            }
        }
    };
    private Paint mSwipePaint;
    private Paint mTextPaint;
    private Paint mPercentPaint;

    public CircleRingView(Context context) {
        this(context, null);
    }

    public CircleRingView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initParams(context);
    }

    private void initParams(Context context) {
        //圆弧Paint
        mRingPaint = new Paint();
        mRingPaint.setStrokeWidth(Px2DpUtil.dp2px(context, 3));
        mRingPaint.setAntiAlias(true);
        mRingPaint.setStyle(Paint.Style.STROKE);
        mRingPaint.setColor(ContextCompat.getColor(context, R.color.white));
        //圆弧上的圆的Paint
        mPointPaint = new Paint();
        mPointPaint.setStrokeWidth(Px2DpUtil.dp2px(context, 1));
        mPointPaint.setAntiAlias(true);
        mPointPaint.setStyle(Paint.Style.FILL);
        mPointPaint.setColor(ContextCompat.getColor(context, R.color.c_3ec88e));
        //进度条Paint
        mSwipePaint = new Paint();
        mSwipePaint.setStrokeWidth(Px2DpUtil.dp2px(context,3));
        mSwipePaint.setAntiAlias(true);
        mSwipePaint.setStyle(Paint.Style.STROKE);
        mSwipePaint.setColor(ContextCompat.getColor(context, R.color.bg_gradient_start));

        //进度值Paint
        mTextPaint = new Paint();
        mTextPaint.setStrokeWidth(Px2DpUtil.dp2px(context, 1));
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setColor(ContextCompat.getColor(context, R.color.c_3ec88e));
        mTextPaint.setTextSize(Px2DpUtil.sp2px(context,40));

        //百分号Paint
        mPercentPaint = new Paint();
        mPercentPaint.setStrokeWidth(Px2DpUtil.dp2px(context, 1));
        mPercentPaint.setAntiAlias(true);
        mPercentPaint.setStyle(Paint.Style.FILL);
        mPercentPaint.setColor(ContextCompat.getColor(context, R.color.c_3ec88e));
        mPercentPaint.setTextSize(Px2DpUtil.sp2px(context,25));
        //Rectf所需要
        mArcDis = Px2DpUtil.dp2px(context, 20);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        RectF rectF = new RectF();
        rectF.left = mArcDis;
        rectF.top = mArcDis;
        rectF.right = width - mArcDis;
        rectF.bottom = height - mArcDis;
        canvas.rotate(90, width / 2, height / 2);
        //正常圆弧
        canvas.drawArc(rectF, 45, 270, false, mRingPaint);
        if (mSwipeAngle>=0&&mSwipeAngle <= 45) {
            mSwipeAngle = 45;
            mPointAngle=45;
        } else if (mSwipeAngle > 315 & mSwipeAngle <= 360) {
            mSwipeAngle = 315;
            mPointAngle = 315;
        }
        mCircleX = width / 2;
        mCircleY = height / 2;
        if(mSwipeAngle<=mPointAngle) {
            float radius = (float) ((width - mArcDis - mArcDis) / 2);
            float pointX = (float) (mCircleX + radius * Math.cos(mSwipeAngle * 3.14 / 180));
            float pointY = (float) (mCircleY + radius * Math.sin(mSwipeAngle * 3.14 / 180));
            //进度圆弧,模仿进度条
            canvas.drawArc(rectF, 45, mSwipeAngle-45, false, mSwipePaint);
            //圆弧上的圆
            canvas.drawCircle(pointX, pointY, Px2DpUtil.dp2px(getContext(), 10), mPointPaint);
            canvas.rotate(-90, width / 2, height / 2);
            //测量文本宽度
            float v = mTextPaint.measureText(String.valueOf((int) Math.floor((float) (mSwipeAngle - 45) / 270 * 100)));
            //绘制文本
            canvas.drawText(String.valueOf((int)Math.floor((float)(mSwipeAngle-45)/270*100)),mCircleX-(int)v/2,mCircleY+Px2DpUtil.dp2px(getContext(),10),mTextPaint);
            //绘制百分号
            canvas.drawText("%",mCircleX+(int)v/2,mCircleY+Px2DpUtil.dp2px(getContext(),10),mPercentPaint);
            mHandler.sendEmptyMessageDelayed(0, 10);
        }
    }
    //需要画的进度值
    public void setProgressValue(int value){
        int swipeAngle = (int) (((float)value / 100) * 360);
        mPointAngle=  swipeAngle;
        mHandler.sendEmptyMessageDelayed(0, 10);
    }
    //停止绘制View
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHandler.removeMessages(0);
        mHandler=null;
    }
}

到这里,整个控件的实现方法就都写完了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.10.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档