Android自定义仪表盘
来源:互联网 发布:数据挖掘及应用是什么 编辑:程序博客网 时间:2024/05/16 08:11
前几天项目中用到一个上阵指数大盘指数仪表图效果如下:
一开始觉得用自定义View来写这个界面,而且仪表盘的图片也给好了,本来想这会非常简单,结果因为指针也是一张图片,指针的圆心不好控制,在给数值的时候总是会有略微的偏差看,尤其是在转着转着的时候就看出来,这是因为指针本身有宽度的问题,代码如下:
public class DashboardCustom extends View {
private Paint paint;private Paint textPaint;int speed = 0;float radius;private Bitmap back;private Bitmap center;private Bitmap arrow;public DashboardCustom(Context context) { this(context, null, 0);}public DashboardCustom(Context context, AttributeSet attrs) { this(context, attrs, 0);}public DashboardCustom(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); /** * 获得我们所定义的自定义样式属性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DashboardCustom, defStyleAttr, 0); speed = a.getInt(R.styleable.DashboardCustom_speed, 0); paint = new Paint(); textPaint = new Paint(); radius = a.getDimension(R.styleable.DashboardCustom_radius, 200); back = BitmapFactory.decodeResource(getResources(), R.drawable.dash); arrow = BitmapFactory.decodeResource(getResources(), R.drawable.arrow); a.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width; int height; super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { float needWidth = back.getWidth(); int desired = (int) (getPaddingLeft() + needWidth + getPaddingRight()); width = desired; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { float needWidth = back.getHeight(); int desired = (int) (getPaddingTop() + needWidth + getPaddingBottom()); height = desired; } setMeasuredDimension(width, height);}@Overrideprotected void onDraw(Canvas canvas) { int backWidth = back.getWidth(); int backHeight = back.getHeight(); //绘制表盘 canvas.drawBitmap(back, 0, 0, paint); //绘制指针 float arc = (speed % 100) * 240 / 200; Matrix matrix = new Matrix(); matrix.postRotate(arc); Bitmap dstbmp = Bitmap.createBitmap(arrow, 0, 0, arrow.getWidth(), arrow.getHeight(), matrix, true); if (arc >= 0) canvas.drawBitmap(dstbmp, backWidth / 2 - arrow.getWidth() / 2 + (int) (arrow.getWidth() * Math.sin(arc * Math.PI / 180)), (int) (backWidth / 2 - arrow.getWidth() / 4 - arrow.getHeight() * Math.cos(arc * Math.PI / 180)), null); else { canvas.drawBitmap(dstbmp, backWidth / 2 - arrow.getWidth() / 2 + (int) (arrow.getHeight() * Math.sin(arc * Math.PI / 180)), (int) (backWidth / 2 - arrow.getWidth() / 4 - arrow.getHeight() * Math.cos(arc * Math.PI / 180)), null); } //中心数字 paint.setStrokeWidth(4); paint.setColor(Color.WHITE); paint.setTextSize(30); //抗锯齿 paint.setAntiAlias(true); paint.setTextAlign(Paint.Align.CENTER); canvas.drawText(speed % 100 + "", backWidth / 2, backHeight, paint);}public void setSpeed(int speed) { this.speed = speed; invalidate();}
}
搞了一天也没有调整好角度,于是退而求其次,好好的分析了一下思路,既然是指针是一张图片,那我就把它固定一个点,然后写个动画让其旋转不就好了么 ,于是有了下面的一种思路,把布局写好,然后写一个动画,完美解决,因为比较简单就不一一讲代码了.
public class DashboardLayout extends RelativeLayout {
private ImageView img_dashboard;
private ImageView img_arrow;
private TextView tv_num;
private float mIndex_num;
private Context context;
public DashboardLayout(Context context) { this(context, null, 0);}public DashboardLayout(Context context, AttributeSet attrs) { this(context, attrs, 0);}public DashboardLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; initView(context);}public void initView(Context context) { View.inflate(context, R.layout.dashboar_view, DashboardLayout.this); img_dashboard = (ImageView) this.findViewById(R.id.img_dashboard); img_arrow = (ImageView) this.findViewById(R.id.img_arrow); tv_num = (TextView) this.findViewById(R.id.tv_num);}float mFromDegrees = 0;float mToDegrees = 0;public void setIndexNum(float index_num) { this.mIndex_num = index_num; if (mIndex_num > 100f) { mIndex_num = 100f; } if (mIndex_num < -100f) { mIndex_num = -100f; } mToDegrees = (index_num) * 240 / 200; RotateAnimation rotateAnimation = new RotateAnimation(mFromDegrees, mToDegrees, 27, 82); rotateAnimation.setDuration(500); rotateAnimation.setFillAfter(true); img_arrow.startAnimation(rotateAnimation); mFromDegrees = mToDegrees; setText();}public void setText() { tv_num.setText(mIndex_num + "");}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/img_dashboard" android:layout_width="101dp" android:layout_height="76dp" android:src="@drawable/dash" /> <ImageView android:id="@+id/img_arrow" android:layout_width="27.5dp" android:layout_height="41dp" android:layout_centerHorizontal="true" android:layout_marginTop="9.5dp" android:src="@drawable/zhizhen_black" /> <TextView android:id="@+id/tv_num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="60dp" android:text="00" android:textSize="15sp" /> </RelativeLayout>
项目源码地址:https://github.com/gexiangjie/DashboardView
0 0
- Android自定义仪表盘视图
- Android自定义仪表盘
- Android自定义仪表盘
- Android 自定义仪表盘
- 时尚仪表盘 Android 自定义View
- Android自定义View之仪表盘
- 自定义仪表盘
- android 自定义View 仪表盘 DashboardView 的实现
- Android 自定义View之八等份仪表盘
- android 自定义控件之汽车仪表盘
- Android仪表盘
- Android 仪表盘
- 手把手带你画一个 时尚仪表盘 Android 自定义View
- 手把手带你画一个 时尚仪表盘 Android 自定义View
- Android自定义控件—仿仪表盘进度控件ArcProgressBar
- 手把手带你画一个 时尚仪表盘 Android 自定义View
- 手把手带你画一个 时尚仪表盘 Android 自定义View
- Android自定义View----时钟/仪表盘的简单实现
- SDU 1247 LCA
- 枚举
- 1015. 德才论 (25)
- 概率DP
- bzoj 3887 tarjan+拓扑排序
- Android自定义仪表盘
- ios--Quartzcore核心动画框架的学习
- 树套树-线段树套线段树
- 全卷机神经网络图像分割(U-net)-keras实现
- C#学习笔记(一)
- C++中引用的基础知识
- 解决eclipse中配置struts.xml时没有提醒的问题
- java如何打印万年历
- 2D贪吃蛇小游戏!!!