继续练习自定义View,这次带来的圆形进度条控件与之前的圆形百分比控件大同小异,这次涉及到了渐变渲染以及画布旋转等知识点,效果如下:
虽然步骤类似,但是我还是要写,毕竟基础的东西就是要多练
1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:
<&#63;xml version="1.0" encoding="utf-8"&#63;>
2、新建CircleProgressView继承View,重写构造方法:
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); }
3、在第三个构造方法中获取自定义属性的值:
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();
4、创建画图所使用的对象,如Paint、Rect、RectF:
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();
5、重写onMeasure()方法,计算自定义View的宽高:
@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; }
6、重写onDraw()方法,绘制圆弧、刻度线和百分比文本、标签说明文本,注意坐标的计算:
@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
7、暴露一个动态设置百分比的方法:
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(); }
8、在activity_main.xml布局文件中使用该View:
<&#63;xml version="1.0" encoding="utf-8"&#63;>
9、在MainActivity中设置监听,传入百分比:
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); } });
代码下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。