android实现简单仪表盘效果

Kamaria ·
更新时间:2024-09-21
· 309 次阅读

本文实例为大家分享了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, "中间的字");



仪表盘 Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号