自定义控件------------车表盘
来源:互联网 发布:公司网站 php源代码 编辑:程序博客网 时间:2024/04/26 17:11
先前在一篇博客上看到博主做的表盘,正好自己最近也在看Android的自定义控件也就玩了一下。
效果图如下:
同时对于表盘的动态展示 , 其实也可以不用自己来写线程 。我们可以使用onDraw的唤醒方法直接进行重画界面,而不需要自己写一个线程不断通过监听参数的变化,再去唤醒onDraw。
public class CarView extends View implements Runnable{
private Paint text;private Paint speedPaint;private Paint background;private Paint onePaint;private Paint twoPaint;private Paint threePaint;private Paint fourPaint;private Paint pointPaint;private float circleXY;private float radius1;private float radius2;private int angle;private Integer speed = 0;private RectF rect;private RectF circleRect;private int type = 2;private boolean start;public CarView(Context context) { super(context); init();}public CarView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init();}public CarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init();}private void init(){ this.text = new Paint(); this.text.setTextSize(50); this.text.setColor(Color.WHITE); this.background = new Paint(); this.background.setStyle(Paint.Style.FILL_AND_STROKE); this.background.setColor(0xFF343434); this.speedPaint = new Paint(); this.speedPaint.setColor(Color.BLUE); this.speedPaint.setStyle(Paint.Style.FILL); this.speedPaint.setAlpha(120); this.onePaint = new Paint(); this.onePaint.setStrokeWidth(12); this.onePaint.setStyle(Paint.Style.STROKE); this.onePaint.setColor(0xE73F51B5); this.twoPaint = new Paint(); this.twoPaint.setStrokeWidth(10); this.twoPaint.setStyle(Paint.Style.STROKE); this.twoPaint.setColor(0x7E3F51B5); this.threePaint = new Paint(); this.threePaint.setStrokeWidth(5); this.threePaint.setStyle(Paint.Style.STROKE); this.threePaint.setColor(0xBF3F6AB5); this.fourPaint = new Paint(); this.fourPaint.setStrokeWidth(5); this.fourPaint.setColor(0xBF3F6AB5); this.fourPaint.setStyle(Paint.Style.STROKE); this.pointPaint = new Paint(); this.pointPaint.setStrokeWidth(5); this.pointPaint.setColor(0xBF3F6AB5); this.pointPaint.setStyle(Paint.Style.FILL); WindowManager manager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(metrics); circleXY = metrics.widthPixels / 2; radius1 = (float)(metrics.widthPixels * 0.4 / 2); radius2 = (float)(metrics.widthPixels * 0.8 / 2); rect = new RectF(circleXY - radius2 , circleXY - radius2 , circleXY + radius2 , circleXY + radius2 ); circleRect = new RectF(circleXY - radius1 , circleXY - radius1 , circleXY + radius1 , circleXY + radius1); this.start = false;}@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //表盘的背景 canvas.drawCircle(circleXY,circleXY,radius2 , background); //表盘内部的两个圆 canvas.drawCircle(circleXY , circleXY , radius1 , onePaint); canvas.drawCircle(circleXY , circleXY , radius1 + 10, twoPaint); double gle = 18.0 / 180.0 * Math.PI; Integer in = 210; //这里我使用自己控制角度来进行画表盘是的指针线 //没有使用canvas进行坐标系移动来画 , 使用坐标系移动的话会更简单一些 for(int i = 0; i < 60; i++){ float l = 0.9f; if(i % 6 == 0) l = 0.83f; float x1 = (float)(radius2 * Math.sin(gle)) + circleXY; float y1 = (float)(radius2 * Math.cos(gle)) + circleXY; float x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY; float y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY; canvas.drawLine(x1 ,y1 , x2 , y2 , this.pointPaint); gle = gle + 6.0 / 180 * Math.PI ; if(i != 0 && i != 54 && i % 6 == 0) { switch (in){ case 210: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY - 75; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 20; break; case 180: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY - 95; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 50; break; case 150: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY - 50; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 75; break; case 120: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY - 20; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 60; break; case 90: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY + 20; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 40; break; case 60: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY + 30; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY + 10; break; case 30: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY + 20; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY - 20; break; case 0: x2 = (float)(radius2 * l * Math.sin(gle)) + circleXY ; y2 = (float)(radius2 * l * Math.cos(gle)) + circleXY - 30; break; } canvas.drawText(in.toString(),x2 , y2 , text); in -= 30; } } //表盘的外部的两个圆 canvas.drawCircle(circleXY , circleXY , radius2 , threePaint); canvas.drawCircle(circleXY , circleXY , radius2 + 15 , fourPaint); //这里先画弧 , 后画中心圆上面的速度 , 也是为了避免drawSpeedArc会覆盖中心圆上的字 drawSpeedArc(canvas); drawCenter(canvas);}//表盘内部的速度private void drawCenter(Canvas canvas){ //speed =100; text.setTextSize(100); float w = text.measureText(speed.toString()); canvas.drawText(speed.toString() , circleXY - w / 2, circleXY + w / 5 , text); //单位 text.setTextSize(60); String mask = "km/h"; w = text.measureText(mask); canvas.drawText(mask , circleXY - w / 2 , circleXY + w , text);}//表盘速度的动态展示private void drawSpeedArc(Canvas canvas){ int angle = speed / 5 * 6 ; Log.d("angle: " + angle , "speed/5*6: " + (speed/5*6)); //通过角度控制弧的大小 , 进而展现速度的大小 canvas.drawArc(rect , 144 , angle , true , speedPaint); //上面 画的弧会覆盖表盘内部圆的区域 ,通过重新在那些被覆盖的地方画背景, 反覆盖 canvas.drawArc(circleRect , 144 , angle , true , background);}public void setStart(boolean start){ this.start = start;}public void setType(int type){ this.type = type;}public void setSpeed(int speed){ this.speed = speed; this.postInvalidateDelayed(100);}@Overridepublic void run() { while(start) { switch (type){ case 0 : speed += 3; break; case 1 : speed -= 2; break; case 2: break; } if(speed < 1) speed = 0; else if(speed > 210) speed = 210; try{ Thread.sleep(50); setSpeed(speed); }catch (InterruptedException e){ e.printStackTrace(); } }}
}
主活动:
public class MainActivity extends AppCompatActivity{
private Button up;private CarView car;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initCarView();}private void initCarView(){ car = (CarView)findViewById(R.id.car); up = (Button)findViewById(R.id.up); up.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: car.setType(0); break; case MotionEvent.ACTION_UP: car.setType(1); break; } return false; } });}@Overrideprotected void onResume() { super.onResume(); if(car != null) { car.setStart(true); new Thread(car).start(); }}
}
0 0
- 自定义控件------------车表盘
- android 自定义表盘控件
- QT 自定义控件之速度表盘
- Andoird自定义控件_弧度表盘
- 自定义表盘
- 自定义表盘
- 学习笔记自定义控件之——自定义表盘
- 自定义控件-类表盘体重选择器的实现
- 自定义控件-类表盘体重选择器的实现
- 自定义View 手表表盘
- 自定义表盘探索1
- 自定义View-汽车表盘
- android自定义表盘
- android 自定义表盘
- iOS可复用控件之表盘
- WatchOS2.0 自定义表盘元素
- WatchOS2.0 自定义表盘元素
- 自定义表盘探索之CanvasWatchFaceService
- 比特币敲诈病毒 NSA武器库防御方法
- 黄金圈理论和知识体系
- Spring AOP专业术语定义
- VMware 中Intel VT-x is disabled 解决方法
- [U3D][iOS]问题记录
- 自定义控件------------车表盘
- 修饰符的适用范围
- hdu 2089 不要62 (数位dp)
- ReactNative WebView使用本地HTML在真机上无法显示的问题
- PDF转JPG图片使用ICEPDF,解决水印的问题
- postgresql在windows 环境下的热备hot standby
- intellij idea 常见遇到的问题整理
- BZOJ 1370: [Baltic2003]Gang团伙 并查集
- jar命令详解