我是靠谱客的博主 超帅蓝天,这篇文章主要介绍Android实现指针刻度转盘,现在分享给大家,希望可以做个参考。

本文实例为大家分享了Android实现指针刻度转盘的具体代码,供大家参考,具体内容如下

一. 先上个效果图,实现如图所示刻度转盘和2个文本的绘制,最后1个刻度绘制的比较长一些(后期会添加动画效果,未完待续…):

二. 话不多说,上代码,Timber可使用Log代替,也可根据自身需求将配置属性放到attrs.xml中去:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package com.landleaf.householdtype.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.View; import androidx.annotation.Nullable; import timber.log.Timber; public class PanelTempCircle extends View { private static final String TAG = PanelTempCircle.class.getSimpleName(); //#EFEFEF //#47C496 private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //画笔宽度,线段长度,最后一条大线条的长度 比其他线段长的长度 private int strokeWidth = 7, lineLength = 40, maxLineLength = 10; //绘制文本距离圆 private int txtMargin = 10; //中心点坐标 private int centerX, centerY; //内圆半径,外圆半径 private int innerRadius, outRadius; //绘制文本 private String leftText = "0", rightText = "30"; //绘制文本的字体大小 private int textSize = 25; //背景 or 进度条颜色 private int colorBackground = Color.parseColor("#EFEFEF"); private int colorProgress = Color.parseColor("#18C8C7"); private int colorText = Color.parseColor("#999999"); float fullAngle = 180f; float cutAngle = 90f; //每个线段相隔的宽度 private static final int perAngle = 6; private int startAngle = -12; public PanelTempCircle(Context context) { super(context); initPaint(context, null); } public PanelTempCircle(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(context, attrs); } private void initPaint(Context context, AttributeSet attrs) { paint.setStrokeCap(Paint.Cap.ROUND); paint.setTextSize(textSize); paint.setStrokeWidth(strokeWidth); paint.setTextAlign(Paint.Align.CENTER); paint.setColor(colorBackground); } public PanelTempCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawCircle(startAngle, 60, canvas, paint); } private void drawCircle(float startAngle, float endAngle, Canvas canvas, Paint paint) { for (float i = startAngle; i <= fullAngle - startAngle; i = i + perAngle) { //-12.-6,0,6....180,186,192 //得出坐标 int startM, startN, endM, endN, startX, startY, endX, endY; int startPaintRadius = innerRadius; int endPaintRadius = outRadius; float currentAngle = i; if (i <= 0) { currentAngle = Math.abs(i); } else if (currentAngle > fullAngle) { currentAngle = i - fullAngle; } //当前进度=结束进度 if (i == endAngle) { startPaintRadius = innerRadius - maxLineLength; endPaintRadius = outRadius + maxLineLength; } //起始点 double angleSin = Math.sin(Math.PI * (Math.abs(currentAngle) / fullAngle)); //起始点 高度 宽度 startM = (int) (angleSin * startPaintRadius); startN = (int) Math.sqrt(Math.pow(startPaintRadius, 2) - Math.pow(startM, 2)); //结束点 高度 宽度 endM = (int) (angleSin * endPaintRadius); endN = (int) Math.sqrt(Math.pow(endPaintRadius, 2) - Math.pow(endM, 2)); // Log.i(TAG, startM + "," + startN + "," + endM + "," + endN); //获得起始点和结束点的坐标 if (i < 0) { //第三象限 startX = centerX - startN; endX = centerX - endN; startY = centerY + startM; endY = centerY + endM; } else if (i > fullAngle) { //第二象限 startX = centerX + startN; endX = centerX + endN; startY = centerY + startM; endY = centerY + endM; } else { if (i < cutAngle) { //第四象限 startX = centerX - startN; endX = centerX - endN; startY = centerY - startM; endY = centerY - endM; } else { //第一象限 startX = centerX + startN; endX = centerX + endN; startY = centerY - startM; endY = centerY - endM; } } //设置线条绘制颜色 if (i <= endAngle) { paint.setColor(colorProgress); } else { paint.setColor(colorBackground); } canvas.drawLine(startX, startY, endX, endY, paint); //判断是否需要绘制文本 if (i == startAngle) { int textWidth = getTextWidth(paint, leftText); paint.setColor(colorText); canvas.drawText(leftText, startX + textWidth + txtMargin, startY, paint); Timber.tag(TAG).i("绘制左侧文本:" + (startX + textWidth + txtMargin) + "," + startY); } if (i == fullAngle - startAngle) { int textWidth = getTextWidth(paint, rightText); paint.setColor(colorText); canvas.drawText(rightText, startX - textWidth - txtMargin, startY, paint); Timber.tag(TAG).i("绘制右侧文本:" + (startX - textWidth - txtMargin) + "," + startY); } } } public int getTextWidth(Paint paint, String str) { int iRet = 0; if (str != null && str.length() > 0) { int len = str.length(); float[] widths = new float[len]; paint.getTextWidths(str, widths); for (int j = 0; j < len; j++) { iRet += (int) Math.ceil(widths[j]); } } return iRet; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); innerRadius = (getMeasuredWidth() - lineLength * 2 - maxLineLength * 2) / 2; outRadius = lineLength + innerRadius; Timber.tag(TAG).i("内圈半径:" + innerRadius + ",外圈半径:" + outRadius); centerX = outRadius + maxLineLength; centerY = outRadius + maxLineLength; Timber.tag(TAG).i("中心坐标:(x=" + centerX + ",y=" + centerY + ")"); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (heightMode == MeasureSpec.AT_MOST) { double angleSin = Math.sin(Math.PI * (Math.abs(startAngle) / fullAngle)); int endPaintRadius = outRadius + maxLineLength; int height = (int) (endPaintRadius + angleSin * endPaintRadius); setMeasuredDimension(widthMeasureSpec, height); } } }

三. xml中使用方式:

说明:主要申明宽度即可,高度会在代码中进行计算;

复制代码
1
2
3
4
5
6
7
8
9
<com.landleaf.householdtype.widget.PanelTempCircle android:id="@+id/mptc_set_temp" android:layout_width="270dp" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/tvHumidity" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.3" />

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。

最后

以上就是超帅蓝天最近收集整理的关于Android实现指针刻度转盘的全部内容,更多相关Android实现指针刻度转盘内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(144)

评论列表共有 0 条评论

立即
投稿
返回
顶部