Android 仪表盘
2017-02-08 10:11
253 查看
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>
最后附上本文的源码下载地址:点击下载源码
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件