Android自定义view实现动态模拟时钟。

效果:

一,自定义一个view的大致步骤:

1.自定义View,首先定义一个MyView类继承View类。    

2. 重写View的两个构造器。View是包含四个构造器的,我们必须重写MyWidgetView(Context context, AttributeSet attrs)构造器,因为该构造器的第二个参数是与xml布局文件相联系的,如果没有重写该构造器,将不能在布局中使用该控件。这里我们重写他的两个构造器。    

3.重写onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,定义控件的尺寸:宽度和高度。在布局中使用该控件时会会传入控件的尺寸,只有当传入尺寸之后且调用onMesure之后,控件才会有宽度和高度。    

4.根据需要重写onLayout()    

5.重写onDraw(Canvas canvas)方法,我们在该方法中定义绘制View,当我们在Activity或其他地方使该控件时, UI主线程会调用onDraw方法绘制。

二,自定view的流程图

三,代码示例:

package com.example.mytest;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.Calendar;

public class MyView extends View {
    private int width;//设置高
    private int height;//设置高
    private Paint mPaintLine;//定义一个绘制直线的画笔
    private Paint mPaintSecondLine;//定义一个绘制直线的画笔
    private Paint mPaintInterCircle;//定义一个绘制圆的画笔
    private Paint mPaintOutSideCircle;//定义一个绘制圆的画笔
    private Paint mPaintText;//定义一个绘制文字的画笔
    private Calendar mCalendar;//创建一个时间类
    private static final int NEED_INVALIDATE=0X6666;

//操作UI主线程
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case NEED_INVALIDATE:
//跟新时间
                    mCalendar=Calendar.getInstance();
                    invalidate();
                    sendEmptyMessageDelayed(NEED_INVALIDATE,1000);
                    break;

            }

        }

    };

    public MyView(Context context) {

        super(context);

    }

    public MyView(Context context, AttributeSet attrs) {

        super(context, attrs);

//初始化画直线的画笔
        mPaintLine = new Paint();
        mPaintLine.setAntiAlias(true);//消除锯齿
        mPaintLine.setColor(Color.GRAY);//设置画笔颜色
        mPaintLine.setStyle(Paint.Style.STROKE);//设置为空心
        mPaintLine.setStrokeWidth(10);//设置宽度

// 初始化秒针的画笔
        mPaintSecondLine = new Paint();
        mPaintSecondLine.setAntiAlias(true);//消除锯齿
        mPaintSecondLine.setColor(Color.GRAY);//设置画笔颜色
        mPaintSecondLine.setStyle(Paint.Style.STROKE);//设置为空心
        mPaintSecondLine.setStrokeWidth(7);//设置宽度

//初始化内圆的画笔
        mPaintInterCircle = new Paint();
        mPaintInterCircle.setAntiAlias(true);//消除锯齿
        mPaintInterCircle.setColor(Color.BLACK);
        mPaintInterCircle.setStyle(Paint.Style.STROKE);//设置为空心
        mPaintInterCircle.setStrokeWidth(5);

//初始化外圆的画笔
        mPaintOutSideCircle = new Paint();
        mPaintOutSideCircle.setAntiAlias(true);//消除锯齿
        mPaintOutSideCircle.setColor(Color.BLACK);
        mPaintOutSideCircle.setStyle(Paint.Style.STROKE);//设置为空心
        mPaintOutSideCircle.setStrokeWidth(10);

//绘制文字的画笔
        mPaintText = new Paint();
        mPaintText.setAntiAlias(true);//消除锯齿
        mPaintText.setColor(Color.GRAY);
        mPaintText.setStyle(Paint.Style.STROKE);//设置为空心
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintText.setTextSize(40);
        mPaintText.setStrokeWidth(6);

//初始化日历
        mCalendar = Calendar.getInstance();

//发送一个消息给UI主线程
        handler.sendEmptyMessageDelayed(NEED_INVALIDATE,2000);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 主线程自动调用
        canvas.drawCircle(width / 2, height / 2, 300, mPaintInterCircle);
        canvas.drawCircle(width / 2, height / 2, 320, mPaintOutSideCircle);
        for(int i=1; i<=12;i++){
            canvas.save();//保存当前状态

            canvas.rotate(360 / 12 * i, width / 2, height / 2);

            canvas.drawLine(width / 2, height / 2 - 300, width / 2, height / 2 - 270, mPaintLine);

            canvas.drawText("" + i, width / 2, height / 2 - 240, mPaintText);

            canvas.restore();//回到save()方法保存的状态

        }

       //绘制分针
        int minute= mCalendar.get(Calendar.MINUTE);
        float minuteDegree = minute/60f*360;
        canvas.save();
        canvas.rotate(minuteDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - 200, width / 2, height / 2 + 40, mPaintLine);
        canvas.restore();

       //绘制时针

        int hour= mCalendar.get(Calendar.HOUR);
        float hourDegree = (hour*60+minute)/(12f*60)*360;
        canvas.save();
        canvas.rotate(hourDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - 170, width / 2, height / 2 + 30, mPaintLine);
        canvas.restore();

       //绘制秒针
        int second = mCalendar.get(Calendar.SECOND);
        float secondDegree = second*6;//一秒是6度。
        canvas.save();
        canvas.rotate(secondDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - 220, width / 2, height / 2 + 50, mPaintSecondLine);
        canvas.restore();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

童无极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值