自定义view-仿移动扇形进度条

            效果图如下:

            

            一.图形的拆解

            1,由两个圆弧组成,一个是透明的弧,另一个则是绿色的弧

            2.文字的绘制

            

              1.弧形区域的计算与弧的绘制

               首先要计算出圆弧的半径,根据半径在计算出,弧形显示的区域

               重新onMeasure方法 处理wrapcontent的时候,控件的大小

               

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int htightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        int defaultSize = 600;

        if (widthMode == MeasureSpec.AT_MOST && htightMode == MeasureSpec.AT_MOST )
        {
            setMeasuredDimension(defaultSize,defaultSize);
        } else if (widthMode == MeasureSpec.AT_MOST){

            setMeasuredDimension(defaultSize,height);
        }else if (htightMode == MeasureSpec.AT_MOST){

            setMeasuredDimension(width,defaultSize);
        }else {
            setMeasuredDimension(width,height);
        }
    }
             计算出圆的半径,这里使用控件大小的一半在减去弧形的宽度,在减100

       

 radious = (int) ((Math.min(getWidth(),getHeight()) /2 -  paint.getStrokeWidth()) - 100);
             

              算出弧形所在的区域

            

 rectF.left = getWidth() / 2 - radious;
        rectF.top = getHeight() / 2 - radious;
        rectF.right = getWidth() / 2 + radious;
        rectF.bottom = getHeight() / 2 + radious;
            

           2.绘制文字

          首先计算出中间文字的位置,这里获取控件宽度的一半减去文字大小的一半

          

 paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1);
        paint.setTextSize(40);
        canvas.drawText(total,getWidth() / 2 - paint.measureText(total) /2,getHeight() / 2,paint);
        paint.setTextSize(30);
        canvas.drawText(title,getWidth() / 2 - paint.measureText(total) /2,getHeight() / 2 - paint.measureText(total) / 2,paint);
       这里主要是底部文字高度计算,这里的计算方法与上一节计算弧度的坐标的效果是一样的,具体可以参考上一篇的博客

       

  mPath.addArc(rectF,180,180);
        mMeasure.setPath(mPath,false);
        mMeasure.getPosTan(mMeasure.getLength(), pos, tan);
canvas.drawText(alerady,getWidth() / 2 - paint.measureText(alerady) / 2,pos[1] + paint.measureText(alerady) / 4,paint);

二。这里贴上完整代码

package smartworld.com.hencoder;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by ${charles}     on 2017/7/13.
 *
 * @desc ${TODO}
 */

public class ArcProgress extends View
{
    private Paint paint;
    private int radious;
    private String total = "2371.00M";
    private String title = "可用流量";
    private String alerady = "已用流量27.99M";
    private Path mPath;
    private float[] pos;
    private float[] tan;
    private PathMeasure mMeasure;

    private ValueAnimator valueAnimator;
    private float mAnimatorValue;
    private float percent = 50;

    private int sweepAngle;
    public ArcProgress(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        paint = new Paint();
        paint.setAntiAlias(true);

        mPath = new Path();
        mMeasure = new PathMeasure();
        pos = new float[2];
        tan = new float[2];

        valueAnimator = ValueAnimator.ofFloat(0,1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator)
            {
                mAnimatorValue = (float) valueAnimator.getAnimatedValue();

                float degree  = percent / 100 * 180;

                Log.e("valuAnimator",mAnimatorValue * degree + "");
                sweepAngle = (int) (mAnimatorValue * degree);

                invalidate();
            }
        });
        valueAnimator.setDuration(3000);
//        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.start();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int htightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        int defaultSize = 600;

        if (widthMode == MeasureSpec.AT_MOST && htightMode == MeasureSpec.AT_MOST )
        {
            setMeasuredDimension(defaultSize,defaultSize);
        } else if (widthMode == MeasureSpec.AT_MOST){

            setMeasuredDimension(defaultSize,height);
        }else if (htightMode == MeasureSpec.AT_MOST){

            setMeasuredDimension(width,defaultSize);
        }else {
            setMeasuredDimension(width,height);
        }
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        RectF rectF = new RectF();
        radious = (int) ((Math.min(getWidth(),getHeight()) /2 -  paint.getStrokeWidth()) - 100);
        rectF.left = getWidth() / 2 - radious;
        rectF.top = getHeight() / 2 - radious;
        rectF.right = getWidth() / 2 + radious;
        rectF.bottom = getHeight() / 2 + radious;

        paint.setColor(Color.parseColor("#44000000"));
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);
        canvas.drawArc(rectF,180,180,false,paint);

        mPath.addArc(rectF,180,180);
        mMeasure.setPath(mPath,false);
        mMeasure.getPosTan(mMeasure.getLength(), pos, tan);
        //canvas.drawCircle(pos[0], pos[1], 10, paint);

        paint.setColor(Color.GREEN);
        canvas.drawArc(rectF,180,sweepAngle,false,paint);

        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1);
        paint.setTextSize(40);
        canvas.drawText(total,getWidth() / 2 - paint.measureText(total) /2,getHeight() / 2,paint);
        paint.setTextSize(30);
        canvas.drawText(title,getWidth() / 2 - paint.measureText(total) /2,getHeight() / 2 - paint.measureText(total) / 2,paint);

        paint.setTextSize(35);
        canvas.drawText(alerady,getWidth() / 2 - paint.measureText(alerady) / 2,pos[1] + paint.measureText(alerady) / 4,paint);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值