Android------自定义View圆形进度条2

1.首先在values下建一个attrs.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleProgressView">
        <attr name="arcWidth" format="dimension" />
        <attr name="scaleCount" format="integer" />
        <attr name="startColor" format="color" />
        <attr name="endColor" format="color" />
        <attr name="labelText" format="string" />
        <attr name="textColor" format="color" />
        <attr name="progressTextSize" format="dimension" />
        <attr name="labelTextSize" format="dimension" />
    </declare-styleable>
</resources>

2.自定义View类

/**

 * 自定义圆形进度控件

 */

public class CircleProgressView extends View {


    /* 弧线宽度 */

    private float mArcWidth;

    /* 刻度个数 */

    private int mScaleCount;

    /* 渐变起始颜色 */

    private int mStartColor;

    /* 渐变终止颜色 */

    private int mEndColor;

    /* 渐变颜色数组 */

    private int[] mColorArray;

    /* 标签说明文本 */

    private String mLabelText;

    /* 文本颜色 */

    private int mTextColor;

    /* 百分比文本字体大小 */

    private float mProgressTextSize;

    /* 标签说明字体大小 */

    private float mLabelTextSize;


    /* 背景弧线画笔 */

    private Paint mArcBackPaint;

    /* 百分比值弧线画笔 */

    private Paint mArcForePaint;

    /* 刻度线画笔 */

    private Paint mLinePaint;

    /* 标签说明文本画笔 */

    private Paint mLabelTextPaint;

    /* 百分比文本画笔 */

    private Paint mProgressTextPaint;

    /* 弧线外切矩形 */

    private RectF mArcRectF;

    /* 测量文本宽高的矩形 */

    private Rect mTextRect;


    /* 百分比 */

    private float mProgress;

    /* 百分比对应角度 */

    private float mSweepAngle;


    public CircleProgressView(Context context) {

        this(context, null);

    }


    public CircleProgressView(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }


    public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);

        mArcWidth = ta.getDimension(R.styleable.CircleProgressView_arcWidth, DensityUtils.dp2px(context, 8));

        mScaleCount = ta.getInteger(R.styleable.CircleProgressView_scaleCount, 24);

        mStartColor = ta.getColor(R.styleable.CircleProgressView_startColor, Color.parseColor("#3FC199"));

        mEndColor = ta.getColor(R.styleable.CircleProgressView_endColor, Color.parseColor("#3294C1"));

        mColorArray = new int[]{mStartColor, mEndColor};

        mLabelText = ta.getString(R.styleable.CircleProgressView_labelText);

        mTextColor = ta.getColor(R.styleable.CircleProgressView_textColor, Color.parseColor("#4F5F6F"));

        mProgressTextSize = ta.getDimension(R.styleable.CircleProgressView_progressTextSize, 160);

        mLabelTextSize = ta.getDimension(R.styleable.CircleProgressView_labelTextSize, 64);

        ta.recycle();


        mArcBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mArcBackPaint.setStyle(Paint.Style.STROKE);

        mArcBackPaint.setStrokeWidth(mArcWidth);

        mArcBackPaint.setColor(Color.LTGRAY);


        mArcForePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mArcForePaint.setStyle(Paint.Style.STROKE);

        mArcForePaint.setStrokeWidth(mArcWidth);


        mArcRectF = new RectF();


        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mLinePaint.setStyle(Paint.Style.STROKE);

        mLinePaint.setColor(Color.WHITE);

        mLinePaint.setStrokeWidth(DensityUtils.dp2px(context, 2));


        mProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mProgressTextPaint.setStyle(Paint.Style.FILL);

        mProgressTextPaint.setColor(mTextColor);

        mProgressTextPaint.setTextSize(mProgressTextSize);


        mLabelTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mLabelTextPaint.setStyle(Paint.Style.FILL);

        mLabelTextPaint.setColor(mTextColor);

        mLabelTextPaint.setTextSize(mLabelTextSize);


        mTextRect = new Rect();

    }


    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        setMeasuredDimension(measuredDimension(widthMeasureSpec), measuredDimension(heightMeasureSpec));

    }


    private int measuredDimension(int measureSpec) {

        int result;

        int mode = MeasureSpec.getMode(measureSpec);

        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {

            result = size;

        } else {

            result = 800;

            if (mode == MeasureSpec.AT_MOST) {

                result = Math.min(result, size);

            }

        }

        return result;

    }


    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        mArcRectF.set(mArcWidth / 2, mArcWidth / 2, getWidth() - mArcWidth / 2, getHeight() - mArcWidth / 2);

        //画背景弧线

        canvas.drawArc(mArcRectF, -90, 360, false, mArcBackPaint);

        //设置渐变渲染

        LinearGradient linearGradient = new LinearGradient(getWidth() / 2, 0, getWidth() / 2, getHeight(), mColorArray, null, Shader.TileMode.CLAMP);

        mArcForePaint.setShader(linearGradient);

        //画百分比值弧线

        canvas.drawArc(mArcRectF, -90, mSweepAngle, false, mArcForePaint);

        //画刻度线

        for (int i = 0; i < mScaleCount; i++) {

            canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mArcWidth, mLinePaint);

            //旋转画布

            canvas.rotate(360 / mScaleCount, getWidth() / 2, getHeight() / 2);

        }

        //画百分比文本

        String progressText = mProgress + "%";

        mProgressTextPaint.getTextBounds(progressText, 0, progressText.length(), mTextRect);

        float progressTextWidth = mTextRect.width();

        float progressTextHeight = mTextRect.height();

        canvas.drawText(progressText, getWidth() / 2 - progressTextWidth / 2,

                getHeight() / 2 + progressTextHeight / 2, mProgressTextPaint);

        //画标签说明文本

        mLabelTextPaint.getTextBounds(mLabelText, 0, mLabelText.length(), mTextRect);

        canvas.drawText(mLabelText, getWidth() / 2 - mTextRect.width() / 2,

                getHeight() / 2 - progressTextHeight / 2 - mTextRect.height(), mLabelTextPaint);

    }


    public void setProgress(float progress) {

        Log.e("--> ", progress + "");

        ValueAnimator anim = ValueAnimator.ofFloat(mProgress, progress);

        anim.setDuration((long) (Math.abs(mProgress - progress) * 20));

        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override

            public void onAnimationUpdate(ValueAnimator animation) {

                mProgress = (float) animation.getAnimatedValue();

                mSweepAngle = mProgress * 360 / 100;

                mProgress = (float) (Math.round(mProgress * 10)) / 10;//四舍五入保留到小数点后两位

                invalidate();

            }

        });

        anim.start();

    }

}


3.自己定义一个 DensityUtils类

public class DensityUtils {  

    private DensityUtils() {  

        /* cannot be instantiated */  

        throw new UnsupportedOperationException("cannot be instantiated");  

    }  

 

    public static int dp2px(Context context, float dpVal) {

        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,  

                dpVal, context.getResources().getDisplayMetrics());  

    }  

 

    public static int sp2px(Context context, float spVal) {

        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,  

                spVal, context.getResources().getDisplayMetrics());  

    }  

 

    public static float px2dp(Context context, float pxVal) {

        final float scale = context.getResources().getDisplayMetrics().density;  

        return (pxVal / scale);  

    }  

 

    public static float px2sp(Context context, float pxVal) {

        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);  

    }  

4.xml文件中:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:cpv="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity">


    <com.monkey.circleprogressview.CircleProgressView

        android:id="@+id/circle_progress_view"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        cpv:arcWidth="8dp"

        cpv:endColor="#126b94"

        cpv:labelText="学习进度"

        cpv:labelTextSize="20sp"

        cpv:progressTextSize="55sp"

        cpv:scaleCount="24"

        cpv:startColor="#12d699"

        cpv:textColor="#4F5F6F" />

</RelativeLayout>


5.主界面中

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final CircleProgressView view = (CircleProgressView) findViewById(R.id.circle_progress_view);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                float progress = (float) (Math.random() * 100);
                view.setProgress(progress);
            }
        });
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值