首页 > 系统 > Android > 正文

Android 仪表盘

2019-11-09 17:20:31
字体:
来源:转载
供稿:网友

1:概述

在以前的项目中,需要实现一个根据用户的压力值显示不同的进度(类似仪表盘)圆弧的进度条。实现的原理其实很简单 ,自定义View 重写onDraw()方法在里面同一圆心画三个不同半径颜色实心圆弧,主要了解canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint);的使用,五个参数的意思分别表示,圆弧的位置和大小,圆弧开始角度,圆弧的结束角度,是否经过圆心,画笔, 我们只要动态改变 sweepAngle 参数就能达到我们想要的效果,废话不多说,直接看代码。

说了一大推先上个效果图

优雅的实现圆弧进度条

下面是实现代码

自定义的CustomSectorView.java

package com.example.wem.sectorviewdemo.widget;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.util.Log;import android.view.View;public class CustomSectorView extends View { PRivate static final String TAG = CustomSectorView.class.getSimpleName(); private float startAngle = 180, sweepAngle = 180; private float pointerStartAngle = 180, pointerSweepAngle = 0; private Paint mPaint; public CustomSectorView(Context context) { super(context); } public CustomSectorView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { float width = getWidth(); float height = getHeight(); int left = (int) (width / 6 + 0.5f); Log.d(TAG, "onDraw: width==" + width + " height==" + height); RectF rectF = new RectF(0, 0, width, height); //设置圆弧的位置和大小 mPaint.setColor(0xff8bc5ba);//设置画笔颜色 mPaint.setAntiAlias(true);//取消锯齿 mPaint.setStrokeWidth(5);//设置画笔宽度 mPaint.setStyle(Paint.Style.FILL);//设置画笔为填充模式 canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint); mPaint.setColor(0xff3b083f); canvas.drawArc(rectF, pointerStartAngle, pointerSweepAngle, true, mPaint); mPaint.setColor(Color.WHITE); RectF innerRectf = new RectF(left, left, 5 * left, 5 * left); canvas.drawArc(innerRectf, startAngle, sweepAngle, true, mPaint); } /** * 设置圆弧的角度 * * @param pointerSweepAngle */ public void setPointerSweepAngle(float pointerSweepAngle) { this.pointerSweepAngle = pointerSweepAngle; invalidate(); }}

MainActivity.java

package com.example.wem.sectorviewdemo;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.ImageView;import com.example.wem.sectorviewdemo.widget.CustomSectorView;import java.util.Timer;import java.util.TimerTask;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); @BindView(R.id.start_button) Button mStartButton; @BindView(R.id.stop_button) Button mStopButton; @BindView(R.id.custom_sector) CustomSectorView mCustomSector; @BindView(R.id.pointer_imageview) ImageView mPointerImageview; private Timer mTimer = new Timer(); private int currentMeter = 0; //当前旋转的角度 private int lastMeter = 0; //旋转后的角度 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } @OnClick({R.id.start_button, R.id.stop_button}) public void onClick(View view) { switch (view.getId()) { case R.id.start_button: startTimer(); break; case R.id.stop_button: stopTimer(); break; } } /** * 开启定时任务 */ private void startTimer() { stopTimer(); MeterTimerTask meterTimerTask = new MeterTimerTask(); mTimer.schedule(meterTimerTask, 50, 50); } /** * 关闭定时任务 */ private void stopTimer() { if (mTimer == null) { return; } mTimer.cancel(); mTimer = null; mTimer = new Timer(); } /** * 定时任务 */ private class MeterTimerTask extends TimerTask { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { currentMeter += 1; if (currentMeter >= 180) { currentMeter = 0; } mCustomSector.setPointerSweepAngle(currentMeter); rotateAnimation(lastMeter, currentMeter); lastMeter = currentMeter; } }); } } /** * 指针旋转动画 * * @param fromDegrees 开始角度 * @param toDegrees 结束角度 */ private void rotateAnimation(float fromDegrees, float toDegrees) { ObjectAnimator anim = ObjectAnimator.ofFloat(mPointerImageview, "rotation", fromDegrees, toDegrees); anim.setDuration(50); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (Float) animation.getAnimatedValue(); } }); anim.start(); }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context="com.example.wem.sectorviewdemo.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <Button android:id="@+id/start_button" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="start" /> <Button android:id="@+id/stop_button" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="stop" /> </LinearLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="-100dp" > <com.example.wem.sectorviewdemo.widget.CustomSectorView android:id="@+id/custom_sector" android:layout_width="200dp" android:layout_height="200dp" /> <ImageView android:id="@+id/pointer_imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@mipmap/pointer" /> </RelativeLayout></RelativeLayout>

最后附上本文的源码下载地址:点击下载源码


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表