近来自己手敲了一个圆环进度加载的自定义view,这里用来表示清理系统垃圾的加载,作为了自定义view练手入门。特此分享给大家也练练手。
演示效果:
实现步骤
1.画背景圆环
2.画中心文字
3.画当前进度圆弧
5.画圆轨迹的同心圆
6.实时更新进度
CircleProgressView代码
/**
* create by libo
* create on 2020/7/22
* description 圆环进度加载view
*/
public class CircleProgressView extends View {
/**
* 背景圆环paint
*/
private Paint bgPaint;
/**
* 进度圆环paint
*/
private Paint progressPaint, smallCirclePaint;
private Paint textPaint1, textPaint2;
/**
* 背景圆环半径
*/
private int bgRadus = 60;
/**
* 当前进度百分比,总数为100
*/
private int curPercentProgress = 0;
/**
* 文字显示内容
*/
private String content;
private String fixText;
public CircleProgressView(Context context) {
super(context);
init();
}
public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setBgPaint();
setProgressPaint();
setTextPaint();
}
private void setBgPaint() {
bgPaint = new Paint();
bgPaint.setColor(getResources().getColor(R.color.white));
bgPaint.setStyle(Paint.Style.STROKE);
bgPaint.setStrokeWidth(10);
bgPaint.setAntiAlias(true);
smallCirclePaint = new Paint();
smallCirclePaint.setColor(getResources().getColor(R.color.white));
}
private void setProgressPaint() {
progressPaint = new Paint();
progressPaint.setColor(getResources().getColor(R.color.orange));
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeWidth(14);
progressPaint.setAntiAlias(true);
}
private void setTextPaint() {
textPaint1 = new Paint();
textPaint1.setColor(getResources().getColor(R.color.orange));
textPaint1.setTextSize(50);
textPaint1.setAntiAlias(true);
textPaint2 = new Paint();
textPaint2.setColor(getResources().getColor(R.color.black));
textPaint2.setTextSize(44);
textPaint2.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//圆直径
int bgCircleWidth = dp2px(getContext(), bgRadus * 2);
//圆与矩形外边距
int padding = (getWidth() - bgCircleWidth) / 2;
//居中画背景圆环
RectF rectF = new RectF(padding, padding, padding + bgCircleWidth, padding + bgCircleWidth);
canvas.drawArc(rectF, -90, 360, false, bgPaint);
Rect contentRect = new Rect();
//画中心文字
content = "当前" + curPercentProgress * 2 + "M";
//将文本居中显示,需要获取文本的宽度,再计算左右边距
//获取文本宽度,高度: getTextBounds 是将TextView 的文本放入一个Rect矩形中, 测量TextView的高度和宽度 .witdh() .height()获取
textPaint1.getTextBounds(content, 0, content.length(), contentRect);
canvas.drawText(content, (getWidth() - contentRect.width()) / 2, (getHeight() - contentRect.height()) / 2, textPaint1);
fixText = "垃圾文件";
textPaint2.getTextBounds(fixText, 0, fixText.length(), contentRect);
canvas.drawText(fixText, (getWidth() - contentRect.width()) / 2, (getHeight() + contentRect.height() * 2) / 2, textPaint2);
//画进度圆弧
/**
* 参数:(中文)
* oval - 用于确定圆弧形状与尺寸的椭圆边界(即椭圆外切矩形)
* startAngle - 开始角度(以时钟3点的方向为0°,12点钟为-90°,顺时针为正方向)
* sweepAngle - 扫过角度 圆弧范围为 startAngle-startAngle+sweepAngle,如果sweepAngle为0,则不显示圆弧
* useCenter - 是否包含圆心,true即为扇形,false为圆弧
* paint - 绘制圆弧的画笔
*/
RectF rectFProgress = new RectF(padding, padding, padding + bgCircleWidth, padding + bgCircleWidth);
canvas.drawArc(rectFProgress, -90, curPercentProgress * 360 / 100, false, progressPaint);
drawThumb(canvas, bgCircleWidth / 2);
}
/**
* 更新当前进度
*
* @param progress 进度值范围 0-100
*/
public void updateProgress(int progress) {
if (progress < 0 || progress > 100) {
return;
}
curPercentProgress = progress;
invalidate();
}
private void drawThumb(Canvas canvas, int r) {
//画终端同心圆
float centerX = getWidth() / 2;
float centerY = getHeight() / 2;
float angle = (float) (curPercentProgress * 360 / 100 * Math.PI / 180); // *Math.PI/180将角度转为弧度,PI为180度
//需要将圆实时画在圆进度轨迹上,简单地用到了三角函数计算,(centerX,centerY)为原点,r为半径,轨迹方程为x^2+y^2=r^2; x=sin(angle),y=cos(angle)
float x = (float) (centerX + r * Math.sin(angle));
float y = (float) (centerY - r * Math.cos(angle));
canvas.drawCircle(x, y, dp2px(getContext(), 4), progressPaint);
canvas.drawCircle(x, y, dp2px(getContext(), 3), smallCirclePaint);
}
public static int dp2px(Context context, int dp) {
return (int) (dp * context.getResources().getDisplayMetrics().density);
}
}
进度更新
public class MainActivity extends AppCompatActivity {
private CircleProgressView circleProgressView;
private int progress = 0;
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
progress += 1;
circleProgressView.updateProgress(progress);
if (progress == 100) {
handler.removeMessages(0);
}
handler.sendEmptyMessageDelayed(0, 50);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
circleProgressView = findViewById(R.id.progressview);
handler.sendEmptyMessageDelayed(0, 1000);
}
}
好了,以上就是主要实现代码,详情或需要自己运行的可以垂询github。
网友评论