项目中要使用仪表器的功能,来提醒一些东西,自己也就实现了一个。
这个是单纯draw出来的,没有加入什么图片,画的太潦草了。
自己也有一些疑问,会先提出来,希望知道可以回答解惑。
话不多说,我也不客气了,我先做个残忍的对比,就是想做出的效果和自己做的效果做个对比。
这是要的效果图,感觉很不错,这是在站酷找的设计图
但是自己做出来的就差远了,后来想想也许思路错了,我纠结我当时怎么想的啊,我竟然全是用画出来,我傻啊
用动画效果多好啊,用贴图多好啊。上图吧
这一对比我就不忍目睹啊。。。。。。
但这也是教训,也放上来吧。
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
|
public class RingEstimateView extends
LinearLayout {
private
final Context mContext;
private
int centerX; // 中心x轴
private
int centerY; // 中心y轴
private
int ringWidth; // 颜色环的大小
private
int radius; // 颜色环的半径
private
int spaceOutsideRadian; // 颜色环与外环的距离
private
int spaceInsideRadian; // 颜色环与内环的距离
private
Canvas mCanvas; // 画布
private
mTask task; // 异步重画
// 计算每个环块的弧度
private
float ringRadian = 3 ;
// 环块绘制开始的角度
private
final float startRadian = 136 .5f;
// 环块绘制结束的角度
private
final float endRadian = 360
+ 45 ;
private
static ExecutorService FULL_TASK_EXECUTOR; // 线程池
static
{
FULL_TASK_EXECUTOR = (ExecutorService) Executors.newCachedThreadPool(); // 单线程的线程池
};
public
RingEstimateView(Context context, AttributeSet attrs) {
super (context, attrs);
this .mContext = context;
this .setWillNotDraw( false );
}
@Override
public
void draw(Canvas canvas) {
this .mCanvas = canvas;
ringWidth = dip2px(mContext, 20 ); // 设置圆环的宽度
radius = dip2px(mContext, getWidth() / 8 ); // 设置半径
spaceOutsideRadian = dip2px(mContext, 15 ); // 环与外环的间隙
spaceInsideRadian = dip2px(mContext, radius / 2
- 15 ); // 环与内环的间隙
centerX = getWidth() / 2 ;
centerY = getHeight() / 2 ;
drwaAngleRingForNumber(); // 画成多少块
drawOutAndInCircle(); // 画出外边的圆
if
(task == null ) {
task = new
mTask( "" , 0 );
task.executeOnExecutor(FULL_TASK_EXECUTOR, 0 );
}
task.drawRemind();
super .draw(canvas);
}
/**
* 根据要画成多少块,画
*/
private
void drwaAngleRingForNumber() {
// 初始化画笔
Paint paint = createPaint(
mContext.getResources().getColor(R.color.green), ringWidth);
paint.setAntiAlias( true );
// 绘制弧度的圆环
multipleColor mc = new
multipleColor(); // 生成多种颜色
float
start = startRadian;
// 绘制圆环的范围
RectF oval = createRectF(centerY - radius, radius * 2
+ (centerY - radius), centerX - radius, radius * 2
+ (centerX - radius));
for
(; start < (endRadian); start += ringRadian * 2 ) { // 循环角度,画出环块
paint.setColor(mc.getWhiteColor()); // 设置不同的颜色
mCanvas.drawArc(oval, start, ringRadian, false , paint);
}
}
/**
* 画出内、外边的圆
*/
private
void drawOutAndInCircle() {
int
mRadius = radius + spaceOutsideRadian + ringWidth;
RectF mOval = createRectF(centerY - mRadius, mRadius * 2
+ (centerY - mRadius), centerX - mRadius, mRadius * 2
+ (centerX - mRadius));
Paint mPaint = createPaint(
mContext.getResources().getColor(R.color.floralwhite), 4 );
int
startRadian = 140 ;
mPaint.setAlpha( 150 );
mCanvas.drawArc(mOval, startRadian, 260 , false , mPaint); // 画出弧圆
// 画出两天横线
float
sinX = ( float ) Math.sin( 50
* Math.PI / 180 ) * mRadius;
float
cosY = ( float ) Math.cos( 50
* Math.PI / 180 ) * mRadius;
mCanvas.drawLine(centerX - sinX, centerY + cosY - 1 ,
(centerX - sinX) - 20 , centerY + cosY, mPaint);
mCanvas.drawLine(centerX + sinX, centerY + cosY - 1 ,
(centerX + sinX) + 20 , centerY + cosY, mPaint);
// 画出文字low max
mPaint.setTextSize( 19 );
mPaint.setStrokeWidth( 2 );
mCanvas.drawText( "LOW" , centerX - sinX - 63 , centerY + cosY + 5 , mPaint);
mCanvas.drawText( "MAX" , centerX + sinX + 25 , centerY + cosY + 5 , mPaint);
// 绘制里面的圆
int
contentRadius = radius - spaceInsideRadian;
Paint tPaint = createPaint(
mContext.getResources().getColor(R.color.ghostwhite), 5 );
tPaint.setStyle(Paint.Style.FILL);
mCanvas.drawCircle(centerX, centerY, contentRadius, tPaint);
}
/**
* 画出提醒的内容
*/
public
void drawRemindContent(String remindContent, int
remindLevel) {
task = new
mTask(remindContent, remindLevel);
task.executeOnExecutor(FULL_TASK_EXECUTOR, 0 );
}
class
mTask extends
AsyncTask<Integer, Integer, Void> {
private
String remindContent;
private
int remindLevel;
private
final float pointStartRadian = startRadian + 1 .5f; // 开始画的弧度
private
int pointDrawRadian = 0 ; // 要画的弧度
private
int bufRadian = 0 ; // 存一个过渡的弧度
public
mTask(String remindContent, int
remindLevel) {
this .remindContent = remindContent;
this .remindLevel = remindLevel;
pointDrawRadian = ( int ) ((remindLevel / 100 .0f) * 44 ) * 6 ;
}
@Override
protected
Void doInBackground(Integer... params) {
for
( int i = 0 ; i < pointDrawRadian; i++) {
bufRadian++;
publishProgress(params);
try
{
Thread.sleep( 20 );
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
return
null ;
}
@Override
protected
void onProgressUpdate(Integer... values) {
RingEstimateView. this .postInvalidate();
super .onProgressUpdate(values);
}
/**
* 画出提醒
*/
public
void drawRemind() {
drawOutCircleToColor(); // 画出彩色部分
drawRemindContent(); // 内容
drawRemindPoint();
}
/**
* 画出外面圆的颜色
*/
private
void drawOutCircleToColor() {
float
pointRadian = pointStartRadian + bufRadian; // 指针的角度
// 初始化画笔
Paint paint = createPaint(
mContext.getResources().getColor(R.color.green), ringWidth);
paint.setAntiAlias( true );
// 绘制弧度的圆环
multipleColor mc = new
multipleColor(); // 生成多种颜色
float
start = startRadian;
// 绘制圆环的范围
RectF oval = createRectF(centerY - radius, radius * 2
+ (centerY - radius), centerX - radius, radius * 2
+ (centerX - radius));
for
(; start < (pointRadian); start += ringRadian * 2 ) { // 循环角度,画出环块
paint.setColor(mc.nextColor()); // 设置不同的颜色
mCanvas.drawArc(oval, start, ringRadian, false , paint);
}
}
/**
* 添加指针视图
*/
private
void addPointView() {
int
deviateRadian = 180
+ 45 ; // 视图本来偏离的角度
float
pointRadian = pointStartRadian; // 指针的角度
int
pointX = radius - spaceInsideRadian; // 开始指针离原点的距离
float
cosPoint = ( float ) Math.cos(pointRadian * Math.PI / 180 );
float
sinPoint = ( float ) Math.sin(pointRadian * Math.PI / 180 );
float
pointStartX = (centerX + cosPoint * pointX);
float
pointStartY = (centerY + sinPoint * pointX);
Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(),
R.drawable.accel_pointer);
// rotate(bmp,(int)(deviateRadian + pointRadian));
mCanvas.drawBitmap(bmp, pointStartX, pointStartY, null );
// 定义矩阵对象
Matrix matrix = new
Matrix();
// 缩放原图
matrix.postScale(1f, 1f);
// 向左旋转45度,参数为正则向右旋转
// matrix.postRotate((int) (deviateRadian));
matrix.setSinCos(sinPoint, cosPoint);
Bitmap dstbmp = Bitmap.createBitmap(bmp, 0 , 0 , bmp.getWidth(),
bmp.getHeight(), matrix, true );
// 在画布上绘制旋转后的baby位图
mCanvas.drawBitmap(dstbmp, pointStartX, pointStartY, null );
int
layoutX = px2dip(mContext,
pointStartX - sinPoint * bmp.getWidth());
int
layoutY = px2dip(mContext, pointStartY);
mCanvas.drawBitmap(rotate(bmp, ( int ) (deviateRadian)), pointStartX,
pointStartY, null );
}
/**
* 位图旋转方法
*
* @param b
* @param degrees
* @return
*/
public
Bitmap rotate(Bitmap b, int
degrees) {
if
(degrees != 0
&& b != null ) {
Matrix m = new
Matrix();
m.setRotate(degrees, ( float ) b.getWidth() / 2 ,
( float ) b.getHeight() / 2 );
try
{
Bitmap b2 = Bitmap.createBitmap(b, 0 , 0 , b.getWidth(),
b.getHeight(), m, true );
if
(b != b2) {
b.recycle(); // Bitmap操作完应该显示的释放
b = b2;
}
} catch
(OutOfMemoryError ex) {
}
}
return
b;
}
/**
* 画出提醒的指针
*/
private
synchronized void drawRemindPoint() {
if
(remindLevel < 0 ) {
remindLevel = 0 ;
} else
if (remindLevel > 100 ) {
remindLevel = 100 ;
}
int
pointLength = dip2px(mContext, spaceInsideRadian - ringWidth - 10 );
int
pointX = radius - spaceInsideRadian; // 开始指针离原点的距离
float
pointRadian = pointStartRadian + bufRadian; // 指针的角度
float
cosPoint = ( float ) Math.cos(pointRadian * Math.PI / 180 );
float
sinPoint = ( float ) Math.sin(pointRadian * Math.PI / 180 );
float
pointStartX = (centerX + cosPoint * pointX);
float
pointStartY = (centerY + sinPoint * pointX);
float
pointStopX = (centerX + cosPoint * (pointX + pointLength));
float
pointStopY = (centerY + sinPoint * (pointX + pointLength));
mCanvas.drawLine(
pointStartX,
pointStartY,
pointStopX,
pointStopY,
createPaint(
mContext.getResources()
.getColor(R.color.ghostwhite), 5 ));
}
/**
* 画出提醒的内容
*/
private
synchronized void drawRemindContent() {
// Canvas mCanvas = new Canvas();
// 画出中间的文字
if
(remindContent == null
|| "" .equals(remindContent)) {
return ;
}
// 加上提醒内容
multipleColor mc = new
multipleColor();
Paint tPaint = createPaint(mc.getRemindColor(remindLevel), 10 );
tPaint.setStyle(Paint.Style.FILL);
tPaint.setTextSize( 45 );
tPaint.setFakeBoldText( true );
mCanvas.drawText(remindContent, centerX - 45 , centerY + 45 / 3 , tPaint);
}
}
// 创建一个矩形
private
RectF createRectF( float
top, float
bottom, float
left, float
right) {
RectF mOval = new
RectF();
mOval.top = top;
mOval.bottom = bottom;
mOval.left = left;
mOval.right = right;
return
mOval;
}
private
Paint createPaint( int
paintColor, int
strokeWidth) {
Paint mPaint = new
Paint();
mPaint.setAntiAlias( true ); // 消除锯齿
mPaint.setStyle(Paint.Style.STROKE); // 绘制空心圆
mPaint.setColor(paintColor);
mPaint.setStrokeWidth(strokeWidth);
return
mPaint;
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public
static int dip2px(Context context, float
dpValue) {
final
float scale = context.getResources().getDisplayMetrics().density;
return
( int ) (dpValue * scale + 0 .5f);
}
/**
* 根据手机的分辨率从 px的单位 转成为 dp(像素)
*/
public
static int px2dip(Context context, float
dpValue) {
final
float scale = context.getResources().getDisplayMetrics().density;
return
( int ) (dpValue / scale + 0 .5f);
}
/*
* 生成多种颜色
*/
class
multipleColor {
private
int currentIndex = 0 ;
private
List<Integer> colors;
public
multipleColor() {
colors = new
ArrayList<Integer>();
for
( int i = 0 ; i < 5 ; i++) {
colors.add(Color.rgb( 0 , 255 , 0 ));
}
for
( int i = 0 ; i <= 255 ; i += 12 ) {
int
c = Color.rgb(i, 255 , 0 );
colors.add(c);
}
for
( int i = 255 ; i >= 0 ; i -= 16 ) {
int
c = Color.rgb( 255 , i, 0 );
colors.add(c);
}
for
( int i = 0 ; i < 5 ; i++) {
colors.add(Color.rgb( 255 , 0 , 0 ));
}
}
// 取得颜色
public
int nextColor() {
if
(currentIndex < colors.size()) {
int
color = colors.get(currentIndex);
currentIndex++;
return
color;
}
return
Color.rgb( 255 , 255 , 255 );
}
// 取得白颜色
public
int getWhiteColor() {
return
Color.rgb( 255 , 255 , 255 );
}
/**
* 取得提醒内容的颜色
*
* @return
*/
public
int getRemindColor( int
remindLevel) {
int
colorNum = (remindLevel / 100 ) * 45 ;
return
colors.get(colorNum);
}
}
/**
* 设置背景
*
* @param color
*/
public
void setBackground( int
color) {
this .setBackground(color);
}
} |
视图函数就是这个了,我是懒了,注释都没写多少了。。
使用就是在activity 中加入:
<framework.ui.RingEstimateView
android:id="@+id/bwv_test"
android:layout_width="fill_parent"
android:layout_height="400dp" >
</framework.ui.RingEstimateView>
然后在class中:
tev = (RingEstimateView) findViewById(R.id.bwv_test);
tev.drawRemindContent("急速",100);//这个函数后面int参数可以使用0~100,表示程度