android实现简单仪表盘效果
作者:昊帅 发布时间:2023-05-31 22:37:39
标签:android,仪表盘
本文实例为大家分享了android实现简单仪表盘效果的具体代码,供大家参考,具体内容如下
实现这个效果:
中间的文字很好写,外层的进度条就需要自定义控件了,代码如下:
public class CirCleProgressBar extends View {
private Paint circlePaint;
private Paint textPaint;
private int circleColor;//圆弧颜色
private int circleBgColor;//圆弧背景颜色
private float circleWidth;//圆弧宽度
private float circleBgWidth;//圆弧背景宽度
private int textColor;//字体颜色
private float textSize;//字体大小
private int totalAngle;//总角度
private int startAngle;//开始角度
private float currentProgress;//当前进度
private float maxProgress;//最大进度
private float section;//分段
private float currentAngle;//当前角度
private float lastAngle;
private ValueAnimator progressAnimator;//圆弧动画
private int duration = 1000;//动画时长
private boolean isDefaultText;//是否设置文字显示的值
private String mTextValue;//字体显示的值
public CirCleProgressBar(Context context) {
this(context, null);
}
public CirCleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CirCleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
circlePaint = new Paint();
textPaint = new Paint();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CirCleProgressBar);
circleColor = typedArray.getColor(R.styleable.CirCleProgressBar_circle_color, Color.RED);
circleBgColor = typedArray.getColor(R.styleable.CirCleProgressBar_circle_bg_color, Color.YELLOW);
circleWidth = typedArray.getDimension(R.styleable.CirCleProgressBar_circle_width, 2);
circleBgWidth = typedArray.getDimension(R.styleable.CirCleProgressBar_circle_bg_width, 2);
textColor = typedArray.getColor(R.styleable.CirCleProgressBar_text_color, Color.BLUE);
textSize = typedArray.getDimension(R.styleable.CirCleProgressBar_text_size, 10);
totalAngle = typedArray.getInteger(R.styleable.CirCleProgressBar_total_angle, 360);
startAngle = typedArray.getInteger(R.styleable.CirCleProgressBar_start_angle, 0);
currentProgress = typedArray.getFloat(R.styleable.CirCleProgressBar_current_progress, 0);
maxProgress = typedArray.getFloat(R.styleable.CirCleProgressBar_max_progress, 100);
setCurrentProgress(currentProgress);
setMaxProgress(maxProgress);
//
typedArray.recycle();
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/**
* 画最外层的大圆环
*/
int centre = getWidth() / 2; // 获取圆心的x坐标
int radius = (int) (centre - circleWidth / 2) - 2; // 圆环的半径
circlePaint.setColor(circleBgColor);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setAntiAlias(true);
circlePaint.setStrokeCap(Paint.Cap.ROUND);// 圆头
circlePaint.setStrokeWidth(circleBgWidth);
RectF oval = new RectF(centre - radius - 1, centre - radius - 1, centre + radius + 1, centre + radius + 1); // 用于定义的圆弧的形状和大小的界限
//背景圆
canvas.drawArc(oval, startAngle, totalAngle, false, circlePaint);
//数据圆
circlePaint.setStrokeWidth(circleWidth);
circlePaint.setColor(circleColor);
canvas.drawArc(oval, startAngle, currentAngle, false, circlePaint);
//
textPaint.setAntiAlias(true);
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
float textWidth = textPaint.measureText((int) currentProgress + "");
if(!isDefaultText) {
canvas.drawText(String.valueOf((int)currentProgress), centre - textWidth / 2, centre + textSize / 2, textPaint);
}else {
canvas.drawText(mTextValue, centre - textWidth / 2, centre + textSize / 2, textPaint);
}
//
invalidate();
}
public float getMaxProgress(){
return maxProgress;
}
public void setMaxProgress(float maxProgress){
if(maxProgress < 0){
throw new IllegalArgumentException("max not less than 0");
}
this.maxProgress = maxProgress;
section = totalAngle / maxProgress;
}
public void setAnimationDuration(int duration){
this.duration = duration;
}
public void setCurrentProgress(float progress){
if(progress >= 0){
this.currentProgress = progress;
if(progress > maxProgress){
progress = maxProgress;
}
lastAngle = currentAngle;
setAnimation(lastAngle, progress * section, duration);
}
}
private void setAnimation(float last, float current, int duration){
progressAnimator = ValueAnimator.ofFloat(last, current);
progressAnimator.setDuration(duration);
progressAnimator.setTarget(currentAngle);
progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
currentAngle = (float) valueAnimator.getAnimatedValue();
currentProgress = currentAngle / section;
}
});
progressAnimator.start();
}
public int getCircleColor() {
return circleColor;
}
public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
}
public int getCircleBgColor() {
return circleBgColor;
}
public void setCircleBgColor(int circleBgColor) {
this.circleBgColor = circleBgColor;
}
public float getCircleWidth() {
return circleWidth;
}
public void setCircleWidth(float circleWidth) {
this.circleWidth = circleWidth;
}
public float getCircleBgWidth() {
return circleBgWidth;
}
public void setCircleBgWidth(float circleBgWidth) {
this.circleBgWidth = circleBgWidth;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
/**
* @param isText 为true,自定义设置字体显示
* @param text
*/
public void setText(boolean isText,String text){
isDefaultText = isText;
mTextValue = text;
}
}
需要在attrs中添加:
<declare-styleable name="CirCleProgressBar">
<attr name="circle_color" format="color"/>
<attr name="circle_bg_color" format="color"/>
<attr name="circle_width" format="dimension"/>
<attr name="circle_bg_width" format="dimension"/>
<attr name="text_color" format="color"/>
<attr name="text_size" format="dimension"/>
<attr name="total_angle" format="integer"/>
<attr name="start_angle" format="integer"/>
<attr name="current_progress" format="float"/>
<attr name="max_progress" format="float"/>
</declare-styleable>
使用方法:
在布局文件中直接引用
<com.fm.newcinema.view.CirCleProgressBar
android:id="@+id/cc_cinema_sentiment"
android:layout_width="139dp"
android:layout_height="99dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
app:circle_bg_color="@color/gray_line_ff"
app:circle_bg_width="10dp"
app:circle_color="@color/main_blue"
app:circle_width="10dp"
app:max_progress="100"
app:start_angle="160"
app:text_color="@color/white_ff"
app:text_size="@dimen/size_30px"
app:total_angle="221"/>
其中app:circle_bg_color表示进度条底层的颜色,app:circle_color表示进度条上层的颜色,app:circle_bg_width表示进度条底层的宽度,app:circle_width表示进度条上层的宽度,app:max_progress="100"表示进度条最大进度是100,app:start_angle表示开始的角度,就是进度条从哪个角度开始画,如下图所示
app:total_angle表示整个进度条所需的角度.
在代码中设置旋转的角度,图中进度为30%,由于在布局文件中设置的最大进度是100`app:max_progress="100",所以进行如下设置peocess.setCurrentProgress(30f)
默认情况下,进度条中间显示进度条的值,如果需要自己写值的画,调用这个方法:process.setText(true, "中间的字");
来源:https://blog.csdn.net/huchengzhiqiang/article/details/77966475


猜你喜欢
- 一、首先在Spring Boot项目中,手动添加异常方法进行测试@Transactional(rollbackFor=Exception.c
- JAVA 静态代理模式代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式说白了就是“真实对象”的代表,在访问对象
- 一、引言在移动应用程序的架构设计中,界面与数据即不可分割又不可混淆。在绝大部分的开发经历中,我们都是使用Fragment来进行界面编程,即使
- 今天我来写一篇关于利用WPF来实现Windows的资源管理器功能,当然只是局部实现这个功能,因为在很多时候我们需要来实现对本机
- 一、注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan、@Configur
- 前几天在看一个cameraCTSbug时,结果在一个java for循环上有点蒙。正好赶上这个点总结一下。java中的控制结构:条件结构这里
- 之前开发项目,一直都使用的是外壳程序加子程序的模式,通过外壳程序去启动子程序,外壳程序和子程序之间的通信,是使用配置文件完成的。我总觉得这样
- 什么是Run Dashboard当springcloud的服务有多个时,管理多个服务的启动使用run会不好管理,这样我们就可以使用Run D
- 一、修改ReadOnly属性1、设置整个DataGridView只读:DataGridView.ReadOnly=true;此时用户的新增行
- 本文实例讲述了Hibernate实现批量添加数据的方法。分享给大家供大家参考,具体如下:1.Hibernate_016_Ba
- 首先,说说final。final关键字可以修饰变量,方法,类。final变量:需求:1 需要一个永不改变的编译时常量2 一个运行时被初始化的
- 本文实例讲述了Java基于递归和循环两种方式实现未知维度集合的笛卡尔积。分享给大家供大家参考,具体如下:什么是笛卡尔积?在数学中,两个集合X
- 在我们对gc中的算法有基本概念理解后,要把算法的理念实现还需要依托实际垃圾收集器的使用。因为光靠一些简单的原理不足以支撑整个程序的运行,在回
- RestTemplate反序列化嵌套对象假设某个接口返回的数据如下格式{ "msg" : "ok&
- 浅谈先来说一下“this指针”:C++中通过引入this指针解决该问题,暨:C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,
- SpringBoot2.3.1版本源码一、SpringBoot启动的时候加载主配置类,通过@EnableAutoConfiguration注解
- 一、概念从本质上来说,它就是一个匿名函数,可以用来直接实现接口中的方法,从而简化代码。但是Lambda有一个限制,不能实现接口中的所有方法,
- 首先看一看什么是装箱和拆箱?简单的来说:装箱就是值类型转换为引用类型;拆箱就是引用类型转换为值类型。值类型,包括原类型(Sbyte、Byte
- 前言开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除就是将数据标记为删除,而并非真的物理删除(非DELETE操作),查询时需要携带状
- IComparable<T>.NET 里,IComparable<T>是用来作比较的最常用接口。如果某个类型的实例需