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表示开始的角度,就是进度条从哪个角度开始画,如下图所示

android实现简单仪表盘效果

app:total_angle表示整个进度条所需的角度.
在代码中设置旋转的角度,图中进度为30%,由于在布局文件中设置的最大进度是100`app:max_progress="100",所以进行如下设置peocess.setCurrentProgress(30f)
默认情况下,进度条中间显示进度条的值,如果需要自己写值的画,调用这个方法:process.setText(true, "中间的字");

来源:https://blog.csdn.net/huchengzhiqiang/article/details/77966475

标签:android,仪表盘
0
投稿

猜你喜欢

  • C#找不到类型名"SqlConnection"的有效解决方法

    2022-05-10 09:47:26
  • Java 设计模式原则之迪米特法则详解

    2021-11-17 19:34:32
  • springmvc视图解析流程代码实例

    2023-02-14 04:33:39
  • Java单例模式的几种常见写法

    2023-10-23 18:27:45
  • java 出现Zipexception 异常的解决办法

    2022-11-07 11:03:03
  • Android实现多媒体录音笔

    2022-03-26 17:25:00
  • Spring中实现定时调度的几种方法

    2021-08-29 13:04:44
  • jar包手动添加到本地maven仓库的步骤详解

    2023-11-23 05:09:37
  • SpringBoot使用自定义注解+AOP+Redis实现接口限流的实例代码

    2022-04-11 09:15:45
  • SpringMvc MultipartFile实现图片文件上传示例

    2022-07-30 16:40:45
  • Spring事务失效的场景梳理总结

    2023-02-23 16:23:24
  • 详解Android应用main函数的调用

    2021-09-30 12:01:19
  • 在IntelliJ IDEA中多线程并发代码的调试方法详解

    2022-01-09 03:05:45
  • Spring整合Quartz实现定时任务调度的方法

    2023-07-07 00:55:55
  • 详解Android Studio如何导入第三方类库、jar包和so库

    2022-01-04 22:27:54
  • 详谈jvm--Java中init和clinit的区别

    2022-01-10 10:35:22
  • Java设计模式之代理模式_动力节点Java学院整理

    2021-08-24 05:55:18
  • Android实现文字上下滚动效果

    2023-02-02 07:40:00
  • Java设计模式之Strategy模式

    2023-11-21 03:58:22
  • Unity多屏幕设置的具体方案

    2023-12-12 12:05:24
  • asp之家 软件编程 m.aspxhome.com