自定义view-绘图时钟

来源:互联网 发布:怎么做淘宝联盟分享赚 编辑:程序博客网 时间:2024/05/28 16:14

首先看下效果图,速度被我调快了,秒针转完一圈,分针跳动一格,分针转完一圈,时针跳动一格,完美模拟时钟的效果。

                                                                                                     


要实现如上自定义view,首先继承view,并重写构造方法:

/** * Created by yanjiang on 2015/12/14. */public class ClockView extends View {    public ClockView(Context context) {        super(context);        init();    }    public ClockView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }
init()方法是为了初始化一些操作,写一些只执行一次的操作

   private void init() {        p1 = new Paint();        p2 = new Paint();        p3 = new Paint();        p4 = new Paint();        pFen=new Paint();        pShi=new Paint();        p1.setColor(Color.RED);        p1.setStrokeWidth(4);        p1.setStyle(Paint.Style.STROKE);        p1.setAntiAlias(true);        p2.setColor(Color.RED);        p2.setTextSize(50);        p2.setStyle(Paint.Style.FILL);        p3.setStyle(Paint.Style.FILL);        p3.setColor(Color.GREEN);        p3.setStrokeWidth(2);        p3.setAntiAlias(true);        p4.setColor(getResources().getColor(R.color.sr_color_primary_dark));        pFen.setColor(Color.GRAY);        pFen.setAntiAlias(true);        pFen.setStrokeWidth(8);        pShi.setColor(getResources().getColor(R.color.black));        pShi.setAntiAlias(true);        pShi.setStrokeWidth(15);        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics dm = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(dm);        width = dm.widthPixels;        height = dm.heightPixels;/*初始化分针位置*/        xFen=width/2;        yFen=height/2-width/4;/*初始化时针位置*/        xShi=width/2+width/5;        yShi=height/2;        new MyThread().start();    }
定义画笔以及配置一些参数,和初始化信息。接下来重写onDraw方法,核心绘图部分:

  @Override    protected void onDraw(Canvas canvas) {        Path path = new Path();        RectF rect1 = new RectF(width / 6, (height - width * 2 / 3) / 2, width - (width / 6), height - (height - width * 2 / 3) / 2);        path.addArc(rect1, 225, 315);        int count = 60; //总刻度数        for (int i = 0; i < count; i++) {            if (i % 5 == 0) {                canvas.drawLine(width / 2, height / 2, width / 2, height / 2 + width / 3 + 30, p1);                String num = String.valueOf(i / 5 + 0);                if (num.equals("0")) {                    num = "12";                }                canvas.drawText(num, width / 2 - 15, height / 2 - width / 3 - 50, p2);            } else {                canvas.drawLine(width / 2, height / 2, width / 2, height / 2 + width / 3 + 15, p3);            }            canvas.rotate(360 / count, width / 2, height / 2); //旋转画纸        }        canvas.drawCircle(width / 2, height / 2, width / 3, p4);        canvas.drawCircle(width / 2, height / 2, width / 3, p1);        canvas.drawCircle(width / 2, height / 2, 20, p3);        canvas.drawTextOnPath("全绘图时钟,你值得拥有", path, 0, 60, p2);        canvas.save();        //时针        canvas.drawLine(width / 2, height / 2, xShi, yShi, pShi);//分针        canvas.drawLine(width / 2, height / 2, xFen, yFen, pFen);//秒针        canvas.drawLine(width / 2, height / 2, x, y, p1);        canvas.drawCircle(width / 2, height / 2, 10, p2);        //   canvas.drawLine(width / 2, height / 2, (float) (width/2+(width/3)*Math.cos(30 * Math.PI / 180)), (float) (height/2-(width / 3 * Math.sin(30* Math.PI / 180))), p1);        // canvas.drawLine(width / 2, height / 2 + 35, width / 2 + x, (height - 2 * width / 3) / 2 + 10 + y, p1);        // canvas.rotate(angel, width / 2, height / 2);        // canvas.restore();//duration执行完成后重复执行    }
将动态变化的地方用变量表示,然后开启线程进行变量值的修改,最后重绘:

public class MyThread extends Thread {    @Override    public void run() {        while (true) {            float j, k,jFen,kFen,jShi,kShi;            j = (float) Math.cos(sweepAngle * Math.PI / 180);            k = (float) Math.sin(sweepAngle * Math.PI / 180);            x = width / 2 + j * (width / 3);            y = height / 2 + k * (width / 3);            sweepAngle += 6;            if(sweepAngle==270){                sweepAngle=-90;                sweepAngleFen+=6;                jFen = (float) Math.cos(sweepAngleFen * Math.PI / 180);                kFen = (float) Math.sin(sweepAngleFen * Math.PI / 180);                xFen = width / 2 + jFen * (width / 4);                yFen = height / 2 + kFen * (width / 4);                if(sweepAngleFen==270){                    sweepAngleFen=-90;                    sweepAngleShi+=6;                    jShi = (float) Math.cos(sweepAngleShi * Math.PI / 180);                    kShi = (float) Math.sin(sweepAngleShi * Math.PI / 180);                    xShi = width / 2 + jShi * (width / 5);                    yShi = height / 2 + kShi * (width / 5);                }            }            postInvalidate();            SystemClock.sleep(10);        }    }}

以上即可实现如图功能,将sleep改为1000即可,最后加上手势波动秒针跟随手指旋转功能:

@Overridepublic boolean onTouchEvent(MotionEvent event) {    float j, k;    if (event.getAction() == MotionEvent.ACTION_MOVE) {        x = event.getX();        y = event.getY();        j = (float) ((y - height / 2) / Math.sqrt((x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2)));        k = (float) ((x - width / 2) / Math.sqrt((x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2)));        y = (width / 3) * j + height / 2;        x = (width / 3) * k + width / 2;        if (y > height / 2)            sweepAngle = Math.acos(k) * 180 / Math.PI;        else            sweepAngle = 2* Math.PI- Math.acos(k) * 180 / Math.PI;            Log.e("yan", sweepAngle + "");        invalidate();    }    return true;}
效果如下                                              :

                                                       


2 0
原创粉丝点击