当前位置:首页 > 安卓源码 > 技术博客 >

自定义View实战 : 汽车速度仪表盘

时间:2017-09-06 22:05 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

废话不说 先上效果图。 是不是很酷炫. 看起来觉得很难? 不难 , 其实实现起来很容易。 思路: 1.绘制一个实心的圆做仪表盘背景。 mPaint.setStyle(Paint.Style.FILL); mPaint.setColor( 0xFF343434 ); canvas.drawCircle(pointX,pointY,raduis,mPaint); 2.

废话不说  先上效果图。

 

自定义View实战 : 汽车速度仪表盘 

 

是不是很酷炫.

看起来觉得很难?  不难 , 其实实现起来很容易。

思路:

1.绘制一个实心的圆做仪表盘背景。 

 

 
  1. mPaint.setStyle(Paint.Style.FILL);  
  2. mPaint.setColor(0xFF343434);  
  3. canvas.drawCircle(pointX, pointY, raduis, mPaint);  


 

 

2.绘制外面的两个圆环 和 里面的 两个圆环。

 

 
  1. //外圈2个圆  
  2. mPaint.setStyle(Paint.Style.STROKE);  
  3. mPaint.setColor(0xBF3F6AB5);  
  4. mPaint.setStrokeWidth(4 * mDensityDpi);  
  5. canvas.drawCircle(pointX, pointY, raduis, mPaint);  
  6. mPaint.setStrokeWidth(3 * mDensityDpi);  
  7. canvas.drawCircle(pointX, pointY, raduis - 10 * mDensityDpi, mPaint);  
  8.   
  9. //内圈2个圆  
  10. mPaint.setStrokeWidth(5 * mDensityDpi);  
  11. mPaint.setColor(0xE73F51B5);  
  12. canvas.drawCircle(pointX, pointY, raduis / 2, mPaint);  
  13. mPaint.setColor(0x7E3F51B5);  
  14. canvas.drawCircle(pointX, pointY, raduis / 2 + 5 * mDensityDpi, mPaint);  
  15. mPaint.setStrokeWidth(3 * mDensityDpi);  


 

 

3.绘制仪表盘的刻度。

 

 
  1. /**
  2.  * 绘制刻度
  3.  */  
  4. private void drawScale(Canvas canvas) {  
  5.     for (int i = 0; i < 60; i++) {  
  6.         if (i % 6 == 0) {  
  7.             canvas.drawLine(pointX - raduis + 10 * mDensityDpi, pointY, pointX - raduis + 50 * mDensityDpi, pointY, mPaint);  
  8.         } else {  
  9.             canvas.drawLine(pointX - raduis + 10 * mDensityDpi, pointY, pointX - raduis + 30 * mDensityDpi, pointY, mPaint);  
  10.         }  
  11.         canvas.rotate(6, pointX, pointY);  
  12.     }  
  13. }  


 

 

4.绘制仪表盘的速度标识和中间的速度 和 单位 文字。(这里有好的处理方法请留言)

 

 
  1. /**
  2.  * 绘制速度标识文字
  3.  */  
  4. private void drawText(Canvas canvas, int value) {  
  5.     String TEXT = String.valueOf(value);  
  6.     switch (value) {  
  7.         case 0:  
  8.             // 计算Baseline绘制的起点X轴坐标  
  9.             baseX = (int) (pointX - sRaduis * Math.cos(Math.PI / 5) + textPaint.measureText(TEXT) / 2 + textScale / 2);  
  10.             // 计算Baseline绘制的Y坐标  
  11.             baseY = (int) (pointY + sRaduis * Math.sin(Math.PI / 5) + textScale / 2);  
  12.             break;  
  13.         case 30:  
  14.             baseX = (int) (pointX - raduis + 50 * mDensityDpi + textPaint.measureText(TEXT) / 2);  
  15.             baseY = (int) (pointY + textScale);  
  16.             break;  
  17.         case 60:  
  18.             baseX = (int) (pointX - sRaduis * Math.cos(Math.PI / 5) + textScale);  
  19.             baseY = (int) (pointY - sRaduis * Math.sin(Math.PI / 5) + textScale * 2);  
  20.             break;  
  21.         case 90:  
  22.             baseX = (int) (pointX - sRaduis * Math.cos(2 * Math.PI / 5) - textScale / 2);  
  23.             baseY = (int) (pointY - sRaduis * Math.sin(2 * Math.PI / 5) + 2 * textScale);  
  24.             break;  
  25.         case 120:  
  26.             baseX = (int) (pointX + sRaduis * Math.sin(Math.PI / 10) - textPaint.measureText(TEXT) / 2);  
  27.             baseY = (int) (pointY - sRaduis * Math.cos(Math.PI / 10) + 2 * textScale);  
  28.             break;  
  29.         case 150:  
  30.             baseX = (int) (pointX + sRaduis * Math.cos(Math.PI / 5) - textPaint.measureText(TEXT) - textScale / 2);  
  31.             baseY = (int) (pointY - sRaduis * Math.sin(Math.PI / 5) + textScale * 2);  
  32.             break;  
  33.         case 180:  
  34.             baseX = (int) (pointX + sRaduis - textPaint.measureText(TEXT) - textScale / 2);  
  35.             baseY = (int) (pointY + textScale);  
  36.             break;  
  37.         case 210:  
  38.             baseX = (int) (pointX + sRaduis * Math.cos(Math.PI / 5) - textPaint.measureText(TEXT) - textScale / 2);  
  39.             baseY = (int) (pointY + sRaduis * Math.sin(Math.PI / 5) - textScale / 2);  
  40.             break;  
  41.   
  42.     }  
  43.     canvas.drawText(TEXT, baseX, baseY, textPaint);  
  44. }  
  45.   
  46. /**
  47.  * 绘制中间文字内容
  48.  */  
  49. private void drawCenter(Canvas canvas) {  
  50.     //速度  
  51.     textPaint.setTextSize(60 * mDensityDpi);  
  52.     float tw = textPaint.measureText(String.valueOf(speed));  
  53.     baseX = (int) (pointX - tw / 2);  
  54.     baseY = (int) (pointY + Math.abs(textPaint.descent() + textPaint.ascent()) / 4);  
  55.     canvas.drawText(String.valueOf(speed), baseX, baseY, textPaint);  
  56.   
  57.     //单位  
  58.     textPaint.setTextSize(20 * mDensityDpi);  
  59.     tw = textPaint.measureText("km/h");  
  60.     baseX = (int) (pointX - tw / 2);  
  61.     baseY = (int) (pointY + raduis / 4 + Math.abs(textPaint.descent() + textPaint.ascent()) / 4);  
  62.     canvas.drawText("km/h", baseX, baseY, textPaint);  
  63. }  


 

 

5.绘制速度范围的扇形区域。

 

[java] view plain copy print?
  1. /**
  2.  * 绘制速度区域扇形
  3.  */  
  4. private void drawSpeedArea(Canvas canvas) {  
  5.     int degree;  
  6.     if (speed < 210) {  
  7.         degree = speed * 36 / 30;  
  8.     } else {  
  9.         degree = 210 * 36 / 30;  
  10.     }  
  11.   
  12.     canvas.drawArc(speedRectF, 144, degree, true, speedAreaPaint);  
  13.   
  14.     // TODO: 2016/5/12  
  15.     //不显示中间的内圈的扇形区域  
  16.     mPaint.setColor(0xFF343434);  
  17.     mPaint.setStyle(Paint.Style.FILL);  
  18.     canvas.drawArc(speedRectFInner, 144, degree, true, mPaint);  
  19.     mPaint.setStyle(Paint.Style.STROKE);  
  20.   
  21.   
  22. }  


 

 

6.实现点击让 速度动起来。实现runnable 接口。

 

 
  1. @Override  
  2. public void run() {  
  3.     int speedChange;  
  4.     while (start) {  
  5.         switch (type) {  
  6.             case 1://油门  
  7.                 speedChange = 3;  
  8.                 break;  
  9.             case 2://刹车  
  10.                 speedChange = -5;  
  11.                 break;  
  12.             case 3://手刹  
  13.                 speed = 0;  
  14.             default:  
  15.                 speedChange = -1;  
  16.                 break;  
  17.         }  
  18.         speed += speedChange;  
  19.         if (speed < 1) {  
  20.             speed = 0;  
  21.         }  
  22.         try {  
  23.             Thread.sleep(50);  
  24.             setSpeed(speed);  
  25.         } catch (InterruptedException e) {  
  26.             e.printStackTrace();  
  27.             break;  
  28.         }  
  29.     }  
  30. }  


 

 

在activity中启动线程,设置监听

 

  1.     //设置监听  
  2.     speedUp.setOnTouchListener(new View.OnTouchListener() {  
  3.         @Override  
  4.         public boolean onTouch(View v, MotionEvent event) {  
  5.             switch (event.getAction()) {  
  6.                 case MotionEvent.ACTION_DOWN:  
  7.                     //按下的时候加速  
  8.                     speedControlView.setType(1);  
  9.                     break;  
  10.                 case MotionEvent.ACTION_UP:  
  11.                     //松开做自然减速  
  12.                     speedControlView.setType(0);  
  13.                     break;  
  14.             }  
  15.             return true;  
  16.         }  
  17.     });  
  18.     speedDown.setOnTouchListener(new View.OnTouchListener() {  
  19.         @Override  
  20.         public boolean onTouch(View v, MotionEvent event) {  
  21.             switch (event.getAction()) {  
  22.                 case MotionEvent.ACTION_DOWN:  
  23.                     //按下的时候减速  
  24.                     speedControlView.setType(2);  
  25.                     break;  
  26.                 case MotionEvent.ACTION_UP:  
  27.                     //松开做自然减速  
  28.                     speedControlView.setType(0);  
  29.                     break;  
  30.             }  
  31.             return true;  
  32.         }  
  33.     });  
  34.     shutDown.setOnTouchListener(new View.OnTouchListener() {  
  35.         @Override  
  36.         public boolean onTouch(View v, MotionEvent event) {  
  37.             switch (event.getAction()) {  
  38.                 case MotionEvent.ACTION_DOWN:  
  39.                     //按下的时候拉手刹  
  40.                     speedControlView.setType(3);  
  41.                     break;  
  42.                 case MotionEvent.ACTION_UP:  
  43.                     //松开做自然减速  
  44.                     speedControlView.setType(0);  
  45.                     break;  
  46.             }  
  47.             return true;  
  48.         }  
  49.     });  
  50.   
  51.   
  52. @Override  
  53. protected void onResume() {  
  54.     super.onResume();  
  55.     if (speedControlView != null) {  
  56.         speedControlView.setSpeed(0);  
  57.         speedControlView.setStart(true);  
  58.     }  
  59.     new Thread(speedControlView).start();  
  60.   
  61. }  

 

补上速度设置函数

 

 
  1. // 设置速度 并重绘视图  
  2. public void setSpeed(int speed) {  
  3.     this.speed = speed;  
  4.     postInvalidate();  
  5. }  

 

搞定.

看,是不是很简单。

自定义View实战 : 汽车速度仪表盘 转载https://www.codesocang.com/appboke/36566.html

技术博客阅读排行

最新文章