安卓实现自定义View画时钟,并解决handler内存泄漏问题。

直接上效果图:

安卓实现自定义View画时钟,并解决handler内存泄漏问题。_第1张图片

具体代码如下:(注释已经写得很清楚了哈)

package com.lenz.arouter.clearpwtest;

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.view.View;

import java.lang.ref.WeakReference;
import java.util.Calendar;


public class StudyView extends View {
    private float mWidth, mHeight;
    private int mHours, mMinutes, mSeconds;
    private TimerHandler mHandler;

    //采用弱引用防止内存泄漏
    private static final class TimerHandler extends Handler {

        private WeakReference clockViewWeakReference;

        private TimerHandler(StudyView clockView) {
            clockViewWeakReference = new WeakReference<>(clockView);
        }

        @Override
        public void handleMessage(Message msg) {
            StudyView view = clockViewWeakReference.get();
            if (view != null) {
                view.getTime();
                view.invalidate();//重新绘制
                sendEmptyMessageDelayed(1, 1000);//每1000毫秒一请求
            }
        }
    }

    public StudyView(Context context) {
        this(context, null);
    }

    public StudyView(Context context, AttributeSet attrs) {
        this(context, null, 0);
    }

    public StudyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mHandler = new TimerHandler(this);
        getTime();
        mHandler.sendEmptyMessageDelayed(1, 1000);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //获取屏幕宽高
        mWidth = getWidth();
        mHeight = getHeight();

        Paint paint = new Paint();//定义画笔
        paint.setAntiAlias(true);//开启抗锯齿
        paint.setStrokeWidth(5);//笔的宽
        paint.setColor(Color.BLACK);//颜色
        paint.setTextSize(mWidth / 22);
        //画表盘
        paint.setStyle(Paint.Style.STROKE);//中空圆心
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paint);
        //画圆心
        paint.setColor(Color.BLUE);//重新定义画圆心笔的颜色
        paint.setStyle(Paint.Style.FILL_AND_STROKE);//实心圆
        canvas.drawCircle(mWidth / 2, mHeight / 2, 8, paint);
        paint.setColor(Color.BLACK);
        //画小时刻度,以下那些比例是自己调的不是固定的。
        for (int i = 0; i < 12; i++) {
            canvas.save();
            canvas.rotate(360 / 12 * (1 + i), mWidth / 2, mHeight / 2);
            canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + mWidth / 15, paint);
            canvas.drawText((i + 1) + "", mWidth / 2 - mWidth / 50, mHeight / 2 - mWidth / 2 + mWidth / 8, paint);
            canvas.restore();
        }
        //画分钟刻度
        for (int i = 0; i < 60; i++) {
            canvas.save();
            canvas.rotate(360 / 60 * (1 + i), mWidth / 2, mHeight / 2);
            canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + mWidth / 20, paint);
            canvas.restore();
        }
        //画时针
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(14);
        canvas.save();
        //这里为什么要乘以0.5;
        // 比如九点半,时针应该指在9-10之间的2.5格。
        // 又因为9-10之间占圆盘的30度,则9-10之间一小格为6度,2.5格即为15度
        //15度为30度的0.5,所以这里要记得分钟数要乘以0.5
        canvas.rotate(360 / 12 * mHours + mMinutes * 0.5f, mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, mHeight / 2 - mHeight / 150, mWidth / 2, mHeight / 2 - mHeight / 7, paint);
        canvas.restore();
        
        //绘制分针
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(9);
        canvas.save();
        canvas.rotate(360 / 60 * mMinutes + mSeconds * 0.1f, mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, mHeight / 2 - mHeight / 150, mWidth / 2, mHeight / 2 - mHeight / 6, paint);
        canvas.restore();

        //绘制秒针
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(5);
        canvas.save();
        canvas.rotate(360 / 60 * mSeconds, mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, mHeight / 2 - mHeight / 150, mWidth / 2, mHeight / 2 - mHeight / 4, paint);
        canvas.restore();
    }
    
    //获取时间

    public void getTime() {
        Calendar calendar = Calendar.getInstance();
        mHours = calendar.get(Calendar.HOUR);
        mMinutes = calendar.get(Calendar.MINUTE);
        mSeconds = calendar.get(Calendar.SECOND);
    }
}

 

你可能感兴趣的:(小白探索,Android)