效果展示:
初始界面:
中间界面(点击后进度每次增加5%):
最终界面:
代码:
MeterView类:
注意:浮点类型存在误差,<= 1 实际可能有偏差,最好可能不能达到100%或者超出100%,需要更改数字的精度。
package swu.twj.a13_drawview;
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.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
/**
* 仪表盘
*/
public class MeterView extends View {
private Paint bgPaint;//背景画笔
private Paint progressPaint;//进度画笔
private Paint textPaint;//文字画笔
private float progress;//进度
public MeterView(Context context) {
super(context);
}
public MeterView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
//背景画笔
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgPaint.setColor(Color.BLACK);
bgPaint.setStyle(Paint.Style.STROKE);
bgPaint.setStrokeWidth(40);
bgPaint.setStrokeCap(Paint.Cap.ROUND);//设置两端的类型
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setColor(Color.MAGENTA);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeWidth(40);
progressPaint.setStrokeCap(Paint.Cap.ROUND);//设置两端的类型
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(100);
}
/**
* 固定不变的 就不要放在onDraw方法里面
* 这个方法可能会被调用多次
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
//画初始圆
//确定矩形区域
RectF frame = new RectF(50,100,getWidth()-50,getWidth()-50);
//画一个弧
canvas.drawArc(frame,120,300,false,bgPaint);
//计算进度对应的角度
int angle = (int)(progress*300);
canvas.drawArc(frame,120,angle,false,progressPaint);
//文本内容
String text = (int)(progress*100)+"%";
//计算文字的宽度
int width = (int)textPaint.measureText(text);
//计算文字的矩阵 FontMetrics
Paint.FontMetricsInt fo = textPaint.getFontMetricsInt();
//文字的高度
int height = fo.bottom - fo.top;
//计算向下移动的距离 ascent/2
int space = -fo.ascent/2;
//画文字
canvas.drawText(text,getWidth()/2-width/2,getWidth()/2+space,textPaint);
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
//刷新 重绘
if (progress <= 1.0001) {
invalidate();
}
}
}
主函数:
创建触摸事件,每次触摸都使进度增加5%
package swu.twj.a13_drawview;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
MeterView mv = findViewById(R.id.meter);
if (event.getAction() == MotionEvent.ACTION_DOWN){
//更改进度值:在原有的进度上+0.05
mv.setProgress((float)(mv.getProgress() + 0.05));
}
return true;
}
}
xml文件配置:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<swu.twj.a13_drawview.MeterView
android:id="@+id/meter"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>