1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > android 控件获取rect Android自定义View圆形进度条控件(三)

android 控件获取rect Android自定义View圆形进度条控件(三)

时间:2021-09-16 20:27:39

相关推荐

android 控件获取rect Android自定义View圆形进度条控件(三)

继续练习自定义View,这次带来的圆形进度条控件与之前的圆形百分比控件大同小异,这次涉及到了渐变渲染以及画布旋转等知识点,效果如下:

虽然步骤类似,但是我还是要写,毕竟基础的东西就是要多练

1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:

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 < 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);

}

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:

xmlns:cpv="/apk/res-auto"

xmlns:tools="/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">

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" />

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);

}

});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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