当前位置:网站首页>自定义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);
}
}
边栏推荐
- redis未授权访问(4-unacc)
- Debian 12 Bookworm 尝鲜记
- Kotlin - 延迟初始化和密封类
- The roll call system and array elements find maximum and minimum values for sorting of objects
- 浅谈性能优化:APP的启动流程分析与优化
- A network security guinea pig's learning path - scripting of advanced usage of nmap
- 最简单的FRP内网穿透教程
- 一分钟get:缓存穿透、缓存击穿、缓存雪崩
- 【一句话攻略】彻底理解JS中的回调(Callback)函数
- 挖矿是什么意思?矿工都做了什么?
猜你喜欢

Eric target penetration test complete tutorial

浅谈性能优化:APP的启动流程分析与优化

2022年中高级 Android 大厂面试秘籍,为你保驾护航金九银十,直通大厂

(6) Design of student information management system

一个网络安全小白鼠的学习之路——nmap的基本使用

The CTF introduction of PHP file contains

强化学习笔记:DDPG

Windows下MySQL数据库报“ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:8000‘ (10061)”错误解决

kotlin语法总结(二)

VIKINGS: 1 vulnhub walkthrough
随机推荐
强化学习笔记:DDPG
会计凭证概述、原始凭证、原始凭证的种类、原始凭证的基本内容、原始凭证的填制要求、原始凭证的审核
SGDP(1)——猜数字游戏
OpenCore 黑苹果安装教程
PALISADE:CKKS的使用
Cookie is used to collect the admin privileges CTF foundation problem
命令执行漏洞
元宇宙是一个炒作的科幻概念,还是互联网发展的下半场?
Laravel随笔记录
ontop-vkg 学习1
机器学习1
管理会计(对内)指引、管理会计要素及其具体内容(可能考,考前记一下,推荐记一下四个大点即可)、
Dcat Admin 关闭代码生成器 登录指定地址
svg图片实战:自定义view打造中国地图
The CTF introduction of PHP file contains
关于我的数学建模~
PHP反序列化漏洞
面试必备:Android性能分析与优化实战进阶手册
还原最真实、最全面的一线大厂面试题
重点考:从债劵的角度来看交易性金融资产