900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 自定义View(三)-圆形进度条-百分比进度条

自定义View(三)-圆形进度条-百分比进度条

时间:2020-09-04 03:03:31

相关推荐

自定义View(三)-圆形进度条-百分比进度条

转载请注明出处:/darling_R/article/details/55002345

自定义view小练习:

自定义view,其实很简单,最关键的就是在设计和绘制上,看你想怎么设计,需要给用户提供什么属性,然后在onDraw()方法里利用画笔Paint在画布caves上会出来,只要你熟悉了caves以及paint的使用,相信绘制一个view对你来说就很简单了;

前面一片博客介绍了自定义view的入门,其步骤还是那几步:

1,在res/value下新建attrs.xml文件,定义一些需要暴露出来的属性

<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。新建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 a = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);mArcWidth = a.getDimensionPixelSize(R.styleable.CircleProgressView_arcWidth, DensityUtils.dp2px(context, 5));mScaleCount = a.getInt(R.styleable.CircleProgressView_scaleCount, 20);mStartColor = a.getColor(R.styleable.CircleProgressView_startColor, 0xff3fc199);mEndColor = a.getColor(R.styleable.CircleProgressView_endColor, 0xffFC3B07);mColorArray = new int[]{mStartColor, mEndColor};mLabeText = a.getString(R.styleable.CircleProgressView_labelText);mTextColor = a.getColor(R.styleable.CircleProgressView_textColor, 0xff4f5f6f);mProgressTextSize = a.getDimensionPixelSize(R.styleable.CircleProgressView_progressTextSize, DensityUtils.sp2px(context, 20));mLabeTextSize = a.getDimensionPixelSize(R.styleable.CircleProgressView_labelTextSize, DensityUtils.sp2px(context, 18));a.recycle();mArcBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿// mArcBackPaint.setAntiAlias(true);//抗锯齿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(mLabeTextSize);mTextRect = new Rect();

4。重写onMesure,计算控件的宽高;

@Overrideprotected 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) {//一般为wrap_content;result = Math.min(result, size);}}return result;}

5。重写onDraw,画出所需要的内容:

@Overrideprotected 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(mLabeText, 0, mLabeText.length(), mTextRect);canvas.drawText(mLabeText, getWidth() / 2 - mTextRect.width() / 2,getHeight() / 2 - progressTextHeight / 2 - mTextRect.height(), mLabelTextPaint);}

增加一个可供外部调用的方法,用来传入百分比数值;

/*** 外部设置百分比方法** @param progress*/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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mProgress = (float) animation.getAnimatedValue();mSweepAngle = mProgress * 360 / 100;mProgress = (float) (Math.round(mProgress * 10)) / 10;//四舍五入保留到小数点后两位invalidate();}});anim.start();}

在布局文件里调用:

<com.yh.circleprogressview.CircleProgressViewandroid:id="@+id/circleProgressView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true"app:arcWidth="5dp"app:endColor="#FC3B07"app:labelText="学习进度"app:labelTextSize="18sp"app:progressTextSize="20sp"app:scaleCount="24"app:startColor="#3B6BFA" />

github源码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。