带你体验Android自定义圆形刻度罗盘 仪表盘 实现指针动态改变
近期有一个自定义View的功能,类似于仪表盘的模型,可以将指针动态指定到某一个刻度上,话不多说,先上图
先说下思路
1.先获取自定义的一些属性,初始化一些资源
2.在onMeasure中测量控件的具体大小
3.然后就在onDraw中先绘制有渐变色的圆弧形色带
4.再绘制几个大的刻度和刻度值
5.再绘制两个大刻度之间的小刻度
6.再绘制处于正中间的圆和三角形指针
7.最后绘制实时值
其实这也从侧面体现了一个自定义view的流程
1.继承View,重写构造方法
2.加载自定义属性和其它资源
3.重写onMeasure方法去确定控件的大小
4.重写onDraw方法去绘制
5.如果有点击事件的话,还得重写onTouchEvent或者dispatchTouchEvent去处理点击事件
来上代码吧,具体注释已经写的很详细了
-
public class NoiseboardView extends View {
-
-
final String TAG = "NoiseboardView";
-
-
private int mRadius; // 圆弧半径
-
private int mBigSliceCount; // 大份数
-
private int mScaleCountInOneBigScale; // 相邻两个大刻度之间的小刻度个数
-
private int mScaleColor; // 刻度颜色
-
private int mScaleTextSize; // 刻度字体大小
-
private String mUnitText = ""; // 单位
-
private int mUnitTextSize; // 单位字体大小
-
private int mMinValue; // 最小值
-
private int mMaxValue; // 最大值
-
private int mRibbonWidth; // 色条宽
-
-
private int mStartAngle; // 起始角度
-
private int mSweepAngle; // 扫过角度
-
-
private int mPointerRadius; // 三角形指针半径
-
private int mCircleRadius; // 中心圆半径
-
-
private float mRealTimeValue = 0.0f; // 实时值
-
-
private int mBigScaleRadius; // 大刻度半径
-
private int mSmallScaleRadius; // 小刻度半径
-
private int mNumScaleRadius; // 数字刻度半径
-
-
private int mViewColor_green; // 字体颜色
-
private int mViewColor_yellow; // 字体颜色
-
private int mViewColor_orange; // 字体颜色
-
private int mViewColor_red; // 字体颜色
-
-
private int mViewWidth; // 控件宽度
-
private int mViewHeight; // 控件高度
-
private float mCenterX;//中心点圆坐标x
-
private float mCenterY;//中心点圆坐标y
-
-
private Paint mPaintScale;//圆盘上大小刻度画笔
-
private Paint mPaintScaleText;//圆盘上刻度值画笔
-
private Paint mPaintCirclePointer;//绘制中心圆,指针
-
private Paint mPaintValue;//绘制实时值
-
private Paint mPaintRibbon;//绘制色带
-
-
private RectF mRectRibbon;//存储色带的矩形数据
-
private Rect mRectScaleText;//存储刻度值的矩形数据
-
private Path path;//绘制指针的路径
-
-
private int mSmallScaleCount; // 小刻度总数
-
private float mBigScaleAngle; // 相邻两个大刻度之间的角度
-
private float mSmallScaleAngle; // 相邻两个小刻度之间的角度
-
-
private String[] mGraduations; // 每个大刻度的刻度值
-
private float initAngle;//指针实时角度
-
-
private SweepGradient mSweepGradient ;//设置渐变
-
private int[] color = new int[7];//渐变颜色组
-
-
public NoiseboardView(Context context) {
-
this(context, null);
-
}
-
-
public NoiseboardView(Context context, AttributeSet attrs) {
-
this(context, attrs, 0);
-
}
-
-
public NoiseboardView(Context context, AttributeSet attrs, int defStyleAttr) {
-
super(context, attrs, defStyleAttr);
-
//自定义属性
-
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NoiseboardView, defStyleAttr, 0);
-
-
mRadius = a.getDimensionPixelSize(R.styleable.NoiseboardView_radius, dpToPx(80));
-
mBigSliceCount = a.getInteger(R.styleable.NoiseboardView_bigSliceCount, 5);
-
mScaleCountInOneBigScale = a.getInteger(R.styleable.NoiseboardView_sliceCountInOneBigSlice, 5);
-
mScaleColor = a.getColor(R.styleable.NoiseboardView_scaleColor, Color.WHITE);
-
mScaleTextSize = a.getDimensionPixelSize(R.styleable.NoiseboardView_scaleTextSize, spToPx(12));
-
mUnitText = a.getString(R.styleable.NoiseboardView_unitText);
-
mUnitTextSize = a.getDimensionPixelSize(R.styleable.NoiseboardView_unitTextSize, spToPx(14));
-
mMinValue = a.getInteger(R.styleable.NoiseboardView_minValue, 0);
-
mMaxValue = a.getInteger(R.styleable.NoiseboardView_maxValue, 150);
-
mRibbonWidth = a.getDimensionPixelSize(R.styleable.NoiseboardView_ribbonWidth, 0);
-
-
a.recycle();
-
init();
-
}
-
-
private void init() {
-
-
//起始角度是从水平正方向即(钟表3点钟方向)开始从0算的,扫过的角度是按顺时针方向算
-
mStartAngle = 175;
-
mSweepAngle = 190;
-
-
mPointerRadius = mRadius / 3 * 2;
-
mCircleRadius = mRadius / 17;
-
-
mSmallScaleRadius = mRadius - dpToPx(10);
-
mBigScaleRadius = mRadius - dpToPx(18);
-