自定义控件------------车表盘

来源:互联网 发布:公司网站 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
原创粉丝点击