帮朋友做个圆形加载进度条,
后来发现做的挺简单的,大佬一个比一个厉害
介绍一下:
1.自定义View属性 2.View 的测量 3.计算绘制 View 所需参数 4.圆弧的绘制及渐变的实现 5.文字的绘制
效果图:进度条颜色由浅到深
一共就几个方法:测量-绘制
?·?onMeasure
?·?onDraw
再暴露出去设置进度和总进度的两个方法就可以了
package com.example.yugusuperdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* 圆形进度条控件
* yugu 2022 8/27
*/
public class CircleProgress extends View {
private static final String TAG = "MyProgress";
private Paint _paint;
private RectF _rectF;
private Rect _rect;
private int _current = 20, _max = 100;
//圆弧(也可以说是圆环)的宽度
private float _arcWidth = 35;
//控件的宽度
private float _width;
private int alpha = 0;
public CircleProgress(Context context) {
this(context, null);
}
public CircleProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
_paint = new Paint();
_paint.setAntiAlias(true);
_rectF = new RectF();
_rect = new Rect();
}
public void SetCurrent(int _current) {
Log.i(TAG, "当前值:" + _current + ",最大值:" + _max);
this._current = _current;
invalidate();
}
public void SetMax(int _max) {
this._max = _max;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//getMeasuredWidth获取的是view的原始大小,也就是xml中配置或者代码中设置的大小
//getWidth获取的是view最终显示的大小,这个大小不一定等于原始大小
_width = getMeasuredWidth();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制圆形
//设置为空心圆,如果不理解绘制弧线是什么意思就把这里的属性改为“填充”,跑一下瞬间就明白了
_paint.setStyle(Paint.Style.STROKE);
//设置圆弧的宽度(圆环的宽度)
_paint.setStrokeWidth(_arcWidth);
_paint.setColor(Color.rgb(222, 235, 243));
_paint.setStrokeCap(Paint.Cap.ROUND);
// _paint.setShader(linearGradient);
// _paint.setShadowLayer(10, 10, 10, Color.GRAY);
//大圆的半径
float bigCircleRadius = _width / 2;
//小圆的半径
float smallCircleRadius = bigCircleRadius - _arcWidth;
//绘制小圆
canvas.drawCircle(bigCircleRadius, bigCircleRadius, smallCircleRadius, _paint);
_paint.setColor(Color.rgb(43, 114, 196));
_paint.setAlpha((int) (alpha + ((float) _current / _max) * 280));
_rectF.set(_arcWidth, _arcWidth, _width - _arcWidth, _width - _arcWidth);
//绘制圆弧
canvas.drawArc(_rectF, 270, _current * 360 / _max, false, _paint);
//计算百分比
String txt = _current * 100 / _max + "%";
_paint.setStrokeWidth(9);
_paint.setTextSize(95);
_paint.getTextBounds(txt, 0, txt.length(), _rect);
_paint.setColor(Color.rgb(108, 146, 201));
//绘制百分比
canvas.drawText(txt, bigCircleRadius - _rect.width() / 2, bigCircleRadius + _rect.height() / 2, _paint);
}
}
补充:_paint.setShadowLayer(10, 10, 10, Color.GRAY);设置阴影效果_paint.setColor(Color.rgb(222, 235, 243));rgb随意更换
linearGradient可以设置渐变
attrs文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressbar">
<attr name="radius" format="dimension"/>
<attr name="strokeWidth" format="dimension"/>
<attr name="ringColor" format="color"/>
<attr name="textColor" format="color"/>
</declare-styleable>
</resources>
调用?
<com.example.yugusuperdemo.CircleProgress
android:id="@+id/ps"
android:layout_width="@dimen/dp_200"
android:layout_height="@dimen/dp_200"/>
public class ScanFragment extends Fragment {
private boolean _threadFlag = false;
private CircleProgress myCircleProgress;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_scan, container, false);
initView(view);
return view;
}
private void initView(View view) {
//设置总加载大小为总缓存数量,每秒刷新当前缓存的清理进度去刷新进度条
myCircleProgress = view.findViewById(R.id.ps);
myCircleProgress.SetMax(100);
new Thread(runnable).start();
}
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
} catch (Exception exception) {
}
int j = 0;
while (!_threadFlag && j < 100) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
int finalJ = j;
requireActivity().runOnUiThread(() -> myCircleProgress.SetCurrent(finalJ));
}
}
};
}
比我做的好的大佬很多,这个可以参考:Android自定义View之画圆环(进阶篇:圆形进度条)_游走的大千世界的烤腰子的博客-CSDN博客_android圆弧进度条
|