android使用自定义view制作时钟

在这里插入图片描述

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Calendar;
public class Clock extends View {
    private static final String TAG = "Clock";

    private int width = dp2px(100);
    private int outRadius;
    private int innerRadius;
    private int numberRadius;

    private int hourLineLen;
    private int minuteLineLen ;
    private int secondLineLen;

    private Paint hourPaint;
    private Paint minutePaint;
    private Paint secondPaint;
    private Paint slimPaint;
    private Paint boldPaint;
    private Paint numberPaint;

    private int hour;
    private int minute;
    private int second;
    public Clock(Context context) {
        super(context);
    }

    public Clock(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
        initValue();
    }


    private boolean running=false;
    void updateTime(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (running) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    Calendar calendar = Calendar.getInstance();
                    hour = calendar.get(Calendar.HOUR);
                    minute = calendar.get(Calendar.MINUTE);
                    second = calendar.get(Calendar.SECOND);
                    invalidate();
                }
            }
        }).start();
    }


    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {

        if(visibility==View.VISIBLE){
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_TIME_TICK);
            running=true;
            updateTime();

        }else{
            running=false;
        }
        
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        width=w;
        initValue();
        initPaint();
    }

    private void initValue() {
        outRadius = width / 2;
        innerRadius = (int) (width / 2 * 0.9);
        numberRadius = (int) (width / 2 * 0.8);

        hourLineLen = (int) (width / 2 * 0.4);
        minuteLineLen = (int) (width / 2 * 0.6);
        secondLineLen = (int) (width / 2 * 0.8);
    }

    public Clock(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            this.width = width;
        }
        setMeasuredDimension(this.width, this.width);
    }

    private void initPaint() {
        slimPaint = new Paint();
        slimPaint.setStrokeWidth((float) (width * 0.013));
        slimPaint.setAntiAlias(true);
        slimPaint.setColor(Color.BLACK);
        boldPaint = new Paint();
        boldPaint.setStrokeWidth((float) (width * 0.02));
        slimPaint.setAntiAlias(true);
        boldPaint.setColor(Color.RED);
        hourPaint = new Paint();
        hourPaint.setColor(Color.BLACK);
        hourPaint.setAntiAlias(true);
        hourPaint.setStrokeCap(Paint.Cap.ROUND);
        minutePaint = new Paint();
        minutePaint.setColor(Color.RED);
        minutePaint.setAntiAlias(true);
        minutePaint.setStrokeCap(Paint.Cap.ROUND);
        secondPaint = new Paint();
        secondPaint.setColor(Color.BLACK);
        secondPaint.setAntiAlias(true);
        secondPaint.setStrokeCap(Paint.Cap.ROUND);
        numberPaint = new Paint();
        numberPaint.setColor(Color.BLACK);
        numberPaint.setTextSize((float) (width * 0.066));
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {

        drawScale(canvas);
        Calendar calendar = Calendar.getInstance();
        String time=calendar.get(Calendar.HOUR_OF_DAY)+":"+minute+":"+second;
        float x= (float) getWidth() /2-numberPaint.measureText(time)/2;
        float y= (float) (getHeight()/2+width*0.3);
        canvas.drawText(time,x,y,numberPaint);

        drawHour(canvas);
        drawMinute(canvas);
        drawSecond(canvas);
        drawNumber(canvas);
    }

    private void drawNumber(Canvas canvas) {
        float angle = 90;
        int start = 12;
        for (int i = 0; i < 12; i++) {
            float x = (float) (width / 2 + Math.cos(Math.PI / 180 * angle) * numberRadius);
            float y = (float) (width / 2 - Math.sin(Math.PI / 180 * angle) * numberRadius);
            x -= numberPaint.measureText(String.valueOf(start)) / 2;
            y += numberPaint.measureText(String.valueOf(start)) / 2;
            canvas.drawText(String.valueOf(start), x, y, numberPaint);
            start--;
            angle += 30;
        }
    }
    private void drawSecond(Canvas canvas) {
        secondPaint.setColor(Color.GRAY);
        canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.0166), secondPaint);
        int angele = 90 + (60 - second) * 6;
        float startX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * (angele + 180)) * width * 0.083);
        float startY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * (angele + 180)) * width * 0.083);
        float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * secondLineLen);
        float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * secondLineLen);
        secondPaint.setStrokeWidth((float) (width * 0.0133));
        canvas.drawLine(startX, startY, endX, endY, secondPaint);
    }

    private void drawHour(Canvas canvas) {
        canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.05), hourPaint);
        int angele = 90 + (12 - hour) * 5 * 6;
        float startX = (float) getWidth() / 2;
        float startY = (float) getHeight() / 2;
        float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * hourLineLen);
        float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * hourLineLen);
        hourPaint.setStrokeWidth((float) (width * 0.033));
        canvas.drawLine(startX, startY, endX, endY, hourPaint);
    }

    private void drawMinute(Canvas canvas) {
        canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.033), minutePaint);
        int angele = 90 + (60 - minute) * 6;
        float startX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * (angele + 180)) * width * 0.066);
        float startY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * (angele + 180)) * width * 0.066);
        float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * minuteLineLen);
        float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * minuteLineLen);
        minutePaint.setStrokeWidth((float) (width * 0.0166));
        canvas.drawLine(startX, startY, endX, endY, minutePaint);
    }

    private void drawScale(Canvas canvas) {
        //制作刻度
        float angle = 90;
        for (int i = 0; i < 60; i++) {
            float startX = (float) (outRadius + Math.cos(Math.PI / 180 * angle) * outRadius);
            float endX = (float) (outRadius + Math.cos(Math.PI / 180 * angle) * innerRadius);
            float startY = (float) (outRadius - Math.sin(Math.PI / 180 * angle) * outRadius);
            float endY = (float) (outRadius - Math.sin(Math.PI / 180 * angle) * innerRadius);
            if (i % 5 == 0) {
                canvas.drawLine(startX, startY, endX, endY, boldPaint);
            } else {
                canvas.drawLine(startX, startY, endX, endY, slimPaint);
            }
            angle += 6;
        }
    }


    private int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
    }

}
        <com.app.clock.Clock
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值