Android类似汽车仪表器

项目中要使用仪表器的功能,来提醒一些东西,自己也就实现了一个。

这个是单纯draw出来的,没有加入什么图片,画的太潦草了。

自己也有一些疑问,会先提出来,希望知道可以回答解惑。

话不多说,我也不客气了,我先做个残忍的对比,就是想做出的效果和自己做的效果做个对比。

这是要的效果图,感觉很不错,这是在站酷找的设计图

 Android类似汽车仪表器

但是自己做出来的就差远了,后来想想也许思路错了,我纠结我当时怎么想的啊,我竟然全是用画出来,我傻啊

用动画效果多好啊,用贴图多好啊。上图吧

 

Android类似汽车仪表器

这一对比我就不忍目睹啊。。。。。。

但这也是教训,也放上来吧。

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,表示程度

 

 

 

 
 

Android类似汽车仪表器,布布扣,bubuko.com

Android类似汽车仪表器

上一篇:Winform打砖块游戏制作step by step第4节---小球移动


下一篇:Android 打开对话框