当前位置:网站首页>自定义view实现半圆弧进度条
自定义view实现半圆弧进度条
2022-08-02 03:27:00 【浮空over】
文章目录
一、效果图
二、使用步骤
1.新建CustomView继承自view
代码如下:
public class CustomView extends View {
}
2.定义变量
代码如下:
//外圆弧
private Paint outPaint;
//内圆弧
private Paint innerPaint;
//文字
private Paint mTextPaint;
//矩形
private RectF oval;
//最大进度
private int max = 10;
//当前进度
private int progress = 6;
//文本内容
private String text = "得分 "+ progress + "/" + max;
//圆弧宽度
private int roundWidth = 40;
//圆点
private int mCircleRadius = SizeUtils.dp2px(6);
private Paint mCirclePaint;
private float[] pos =new float[2];
private int viewWidth; //宽度--控件所占区域
private float nowPro = 0;//用于动画
private ValueAnimator animator;
3.构造函数
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(attrs, context);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs, context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initAttrs(attrs, context);
}
4.构造方法
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
5.初始化数据
private void initAttrs(AttributeSet attr, Context context) {
outPaint = new Paint();
outPaint.setColor(Color.parseColor("#F5F6FA"));
outPaint.setAntiAlias(true);
outPaint.setStyle(Paint.Style.STROKE);
outPaint.setStrokeCap(Paint.Cap.ROUND);
outPaint.setStrokeWidth(SizeUtils.dp2px(12));
innerPaint = new Paint();
innerPaint.setColor(Color.parseColor("#667CFF"));
innerPaint.setAntiAlias(true);
innerPaint.setStyle(Paint.Style.STROKE);
innerPaint.setStrokeCap(Paint.Cap.ROUND);
innerPaint.setStrokeWidth(SizeUtils.dp2px(12));
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(Color.parseColor("#131936"));
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextSize(SizeUtils.sp2px(20));
//动画
animator = ValueAnimator.ofFloat(0, progress);
animator.setDuration(1800);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
nowPro = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
6.onMeasure()
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));
}
7.onSizeChanged()
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;//得到宽度以此来计算控件所占实际大小
//计算画布所占区域
oval = new RectF();
oval.left = roundWidth + getPaddingLeft();
oval.top = roundWidth + getPaddingTop();
oval.right = viewWidth - roundWidth - getPaddingRight();
oval.bottom = viewWidth - roundWidth - getPaddingBottom();
}
8.onDraw()
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path outerPath = new Path();
outerPath.arcTo(oval,180,180);
canvas.drawPath(outerPath,outPaint);
SweepGradient sweepGradient = new SweepGradient(getWidth()/2,getWidth()/2,Color.parseColor("#FFFFFF"),Color.parseColor("#0047F7"));
innerPaint.setShader(sweepGradient);
canvas.drawArc(oval, 180, 180 * nowPro / max, false, innerPaint); //绘制圆弧
mCirclePaint = new Paint();
mCirclePaint.setColor(Color.WHITE);
mCirclePaint.setStyle(Paint.Style.FILL);
PathMeasure pathMeasure = new PathMeasure(outerPath,false);
boolean posTan = pathMeasure.getPosTan(pathMeasure.getLength() * nowPro / max, pos, null);
canvas.drawCircle(pos[0],pos[1],mCircleRadius,mCirclePaint);
float textWidth = mTextPaint.measureText(text);
canvas.drawText(text, viewWidth / 2 - textWidth / 2, viewWidth / 2, mTextPaint);
}
9.xml文件
<com.wuchen.viewdemo.CustomView android:id="@+id/customView" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="30dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
三、完整代码(附Demo地址)
package com.wuchen.juexiaofakao;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import com.blankj.utilcode.util.SizeUtils;
public class CustomView extends View {
private Paint outPaint;
private Paint innerPaint;
private Paint mTextPaint;
private RectF oval;
//最大进度
private int max = 10;
//当前进度
private int progress = 6;
//文本内容
private String text = "得分 "+ progress + "/" + max;
//圆弧宽度
private int roundWidth = 40;
private int mCircleRadius = SizeUtils.dp2px(6);
private Paint mCirclePaint;
private float[] pos =new float[2];
private final int[] colors = {
Color.parseColor("#95ACFF"),Color.parseColor("#4379FF")};
private int viewWidth; //宽度--控件所占区域
private float nowPro = 0;//用于动画
private ValueAnimator animator;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(attrs, context);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs, context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initAttrs(attrs, context);
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
private void initAttrs(AttributeSet attr, Context context) {
outPaint = new Paint();
outPaint.setColor(Color.parseColor("#F5F6FA"));
outPaint.setAntiAlias(true);
outPaint.setStyle(Paint.Style.STROKE);
outPaint.setStrokeCap(Paint.Cap.ROUND);
outPaint.setStrokeWidth(SizeUtils.dp2px(12));
innerPaint = new Paint();
innerPaint.setColor(Color.parseColor("#667CFF"));
innerPaint.setAntiAlias(true);
innerPaint.setStyle(Paint.Style.STROKE);
innerPaint.setStrokeCap(Paint.Cap.ROUND);
innerPaint.setStrokeWidth(SizeUtils.dp2px(12));
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(Color.parseColor("#131936"));
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextSize(SizeUtils.sp2px(20));
//动画
animator = ValueAnimator.ofFloat(0, progress);
animator.setDuration(1800);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
nowPro = (float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;//得到宽度以此来计算控件所占实际大小
//计算画布所占区域
oval = new RectF();
oval.left = roundWidth + getPaddingLeft();
oval.top = roundWidth + getPaddingTop();
oval.right = viewWidth - roundWidth - getPaddingRight();
oval.bottom = viewWidth - roundWidth - getPaddingBottom();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path outerPath = new Path();
outerPath.arcTo(oval,180,180);
canvas.drawPath(outerPath,outPaint);
SweepGradient sweepGradient = new SweepGradient(getWidth()/2,getWidth()/2,Color.parseColor("#FFFFFF"),Color.parseColor("#0047F7"));
innerPaint.setShader(sweepGradient);
canvas.drawArc(oval, 180, 180 * nowPro / max, false, innerPaint); //绘制圆弧
mCirclePaint = new Paint();
mCirclePaint.setColor(Color.WHITE);
mCirclePaint.setStyle(Paint.Style.FILL);
PathMeasure pathMeasure = new PathMeasure(outerPath,false);
boolean posTan = pathMeasure.getPosTan(pathMeasure.getLength() * nowPro / max, pos, null);
canvas.drawCircle(pos[0],pos[1],mCircleRadius,mCirclePaint);
float textWidth = mTextPaint.measureText(text);
canvas.drawText(text, viewWidth / 2 - textWidth / 2, viewWidth / 2, mTextPaint);
}
}
边栏推荐
猜你喜欢
A network security guinea pig's learning path - scripting of advanced usage of nmap
链动2+1模式开发系统
链动2+1无限循环系统,2022年起盘成功率超高的模式
uniapp发布到微信小程序:分包、删减代码全过程
laravel-admin FROM表单同行展示问题
PHP deserialization vulnerability
xxe of CTF
管理会计(对内)指引、管理会计要素及其具体内容(可能考,考前记一下,推荐记一下四个大点即可)、
DNS详解
v-bind usage: class dynamic binding object array style style and function method
随机推荐
(1) the print () function, escape character, binary and character encoding, variables, data type, the input () function, operator
同态加密:CKKS原理之旋转(Rotation)
laravel-admin FROM表单同行展示问题
(6) Design of student information management system
PHP反序列化漏洞
Scrapy crawler encounters redirection 301/302 problem solution
Laravel 登录,中间件和路由分组
Google Hacking
解决flex布局warp自动换行下最后一行居中问题
Summary of php function vulnerabilities
关于我的专利、软著~
Laravel 验证唯一时排除修改时的数据
关于我的项目-微信小程序2(uniapp->wx小程序)
公司产品太多了,怎么实现一次登录产品互通?
How to log in to Alibaba Cloud server using the admin account
什么是广告电商商业模式?这几个门派告诉你
Jetpack中各个组件简介
大厂底层必修:“应用程序与 AMS 的通讯实现”
一次代码审计的笔记(CVE-2018-12613 phpmyadmin文件包含漏洞)
同时安装VirtualBox和VMware,虚拟机如何上网