欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

笔记 77 | Launcher表盘时间部件工具类(时,分,秒)

程序员文章站 2022-06-12 22:57:33
...

Author: xy

目前公司常用的制作时间表盘的两个方法:

一,

<AnalogClock

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:dial="@drawable/dial"

        android:hand_hour="@drawable/tr_bar"

        android:hand_minute="@drawable/tr_bar"

/>

此方法最为简便,只需替换素材即可

二,

logic2(findViewById(R.id.img_hour),findViewById(R.id.img_minute),h*30,m*6);

private ObjectAnimator animator1;

        private ObjectAnimator animator2;

        private boolean animatorFlag = true;

        private float currentPoint1 = 0;

        private float currentPoint2 = 0;

        AnimatorSet mAnimatorSet = new AnimatorSet();

        private void logic2(View view1,View view2,final float nowPoint1,final float nowPoint2){

            if(animatorFlag){

                animatorFlag = false;

                animator1 = ObjectAnimator.ofFloat(view1, "rotation",currentPoint1,nowPoint1);

                animator2 = ObjectAnimator.ofFloat(view2, "rotation",currentPoint2,nowPoint2);

                mAnimatorSet.addListener(new AnimatorListenerAdapter(){

                    @Override

                    public void onAnimationEnd(Animator animation) {

                        super.onAnimationEnd(animation);

                        currentPoint1 =  nowPoint1;

                        currentPoint2 =  nowPoint2;

                        animatorFlag = true;

                    }

                });

                mAnimatorSet.playTogether(animator1,animator2);

                mAnimatorSet.setDuration(50);

                mAnimatorSet.start();

            }

        }

调用前辈封装好的工具类
android.animation.AnimatorSet

代码清晰明了,一看便知怎么用,但不知道怎么实现的。

但是,发现这两种方法里都没有秒针的动画,方法一无法实现秒针,方法二由于是封装好的类,查看和修改起来不方便。

于是通过前人栽的树,按自己要求修改完成了可以实现时,分,秒的时间表盘工具类,设置好了图片在布局中直接使用就行了,目前还没发现bug!

主要代码贴出,只当学习使用:

package com.android.launcher2;

import java.util.TimeZone;

import com.android.launcher.R;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.content.res.Resources;

import android.graphics.Canvas;

import android.graphics.drawable.Drawable;

import android.os.Handler;

import android.os.Message;

import android.text.format.Time;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.widget.RemoteViews.RemoteView;

/**

* This widget display an analogic clock with two hands for hours and minutes.

* even add by 20180705

*/

@RemoteView

public class MyAnalogClock extends View {

    private Time mCalendar;

    private Drawable mHourHand;

    private Drawable mMinuteHand;

    private Drawable mSecondHand;

    private Drawable mPointHand;

    private Drawable mDial;

    private int mDialWidth;

    private int mDialHeight;

    private boolean mAttached;

    private float mMinutes;

    private float mHour;

    private boolean mChanged;

    // /增加了秒针显示所用到的秒表

    private static String debug = "MyAnalogClock";

    private static int SECONDS_FLAG = 0;

    private Message secondsMsg;

    private float mSeconds;

    public MyAnalogClock(Context context) {

        this(context, null);

    }

    public MyAnalogClock(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }

    public MyAnalogClock(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

        Resources r = context.getResources();

        if (mDial == null) {

            mDial = r.getDrawable(R.drawable.bg_time);

        }

        if (mHourHand == null) {

            mHourHand = r.getDrawable(R.drawable.hour);

        }

        if (mMinuteHand == null) {

            mMinuteHand = r.getDrawable(R.drawable.minute);

        }

        if (mSecondHand == null) {

            mSecondHand = r.getDrawable(R.drawable.second);

        }

        if (mPointHand == null) {

            mPointHand = r.getDrawable(R.drawable.point);

        }

        mCalendar = new Time();

        mDialWidth = mDial.getIntrinsicWidth();

        mDialHeight = mDial.getIntrinsicHeight();

    }

    /*

     * * 吸附到窗体上

     */

    @Override

    protected void onAttachedToWindow() {

        Log.e(debug, "onAttachedToWindow");

        super.onAttachedToWindow();

        if (!mAttached) {

            mAttached = true;

        }

        mCalendar = new Time();

        // Make sure we update to the current time

        onTimeChanged();

        initSecondsThread();

    }

    private void initSecondsThread() {

        secondsMsg = mHandler.obtainMessage(SECONDS_FLAG);

        Thread newThread = new Thread() {

            @Override

            public void run() {

                while (mAttached) {

                    // 如果这个消息不重新获取的话,

                    // 会抛一个this message is already in use 的异常

                    secondsMsg = mHandler.obtainMessage(SECONDS_FLAG);

                    // /end

                    mHandler.sendMessage(secondsMsg);

                    try {

                        sleep(1000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }

        };

        newThread.start();

    }

    private final Handler mHandler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            switch (msg.what) {

            case 0:

                onTimeChanged();// 重新获取的系统的当前时间,得到时,分,秒

                invalidate();// 强制绘制,调用自身的onDraw();

                break;

            default:

                break;

            }

            super.handleMessage(msg);

        }

    };

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        Log.e(debug, "onMeasure");

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        float hScale = 1.0f;

        float vScale = 1.0f;

        if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) {

            hScale = (float) widthSize / (float) mDialWidth;

        }

        if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) {

            vScale = (float) heightSize / (float) mDialHeight;

        }

        float scale = Math.min(hScale, vScale);

        setMeasuredDimension(resolveSize((int) (mDialWidth * scale),

                widthMeasureSpec), resolveSize((int) (mDialHeight * scale),

                        heightMeasureSpec));

    }

    @Override

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        Log.e(debug, "onSizeChanged");

        super.onSizeChanged(w, h, oldw, oldh);

        mChanged = true;

    }

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        Log.e(debug, "canvas");

        boolean changed = mChanged;

        if (changed) {

            mChanged = false;

        }

        int availableWidth = getWidth();

        int availableHeight = getHeight();

        int x = availableWidth / 2;

        int y = availableHeight / 2;

        final Drawable dial = mDial;

        int w = dial.getIntrinsicWidth();

        int h = dial.getIntrinsicHeight();

        boolean scaled = false;

        //当图片的素材的宽高大于素材所在布局的宽高时

        if (availableWidth < w || availableHeight < h) {

            scaled = true;

            float scale = Math.min((float) availableWidth / (float) w,

                    (float) availableHeight / (float) h);

            canvas.save();

            canvas.scale(scale, scale, x, y);

        }

        if (changed) {

            dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));

        }

        dial.draw(canvas);

        //以上是绘制12个小时背景图

        canvas.save();

        canvas.rotate(mHour / 12.0f * 360.0f, x, y);

        final Drawable hourHand = mHourHand;

        if (changed) {

            w = hourHand.getIntrinsicWidth();

            h = hourHand.getIntrinsicHeight();

            hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y

                    + (h / 2));

        }

        hourHand.draw(canvas);

        canvas.restore();

        //以上是绘制时针

        canvas.save();

        canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);

        final Drawable minuteHand = mMinuteHand;

        if (changed) {

            w = minuteHand.getIntrinsicWidth();

            h = minuteHand.getIntrinsicHeight();

            minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y

                    + (h / 2));

        }

        minuteHand.draw(canvas);

        canvas.restore();

        //以上是绘制分针

        //增加秒针的绘制

        canvas.save();

        canvas.rotate(mSeconds / 60.0f * 360.0f, x, y);

        final Drawable secondHand = mSecondHand;

        if (changed) {

            w = secondHand.getIntrinsicWidth();

            h = secondHand.getIntrinsicHeight();

            secondHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y

                    + (h / 2));

        }

        secondHand.draw(canvas);

        canvas.restore();

        //增加中间遮挡

        final Drawable pointHand = mPointHand;

        if (changed) {

            w = pointHand.getIntrinsicWidth();

            h = pointHand.getIntrinsicHeight();

            pointHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y

                    + (h / 2));

        }

        pointHand.draw(canvas);

        if (scaled) {

            canvas.restore();

        }

    }

    /**

     * 改变时间

     */

    private void onTimeChanged() {

        Log.e(debug, "onTimeChanged");

        mCalendar.setToNow();//获取手机自身的当前时间,而非实际中的标准的北京时间

        int hour = mCalendar.hour;// 小时

        int minute = mCalendar.minute;// 分钟

        int second = mCalendar.second;// 秒

        mSeconds = second;

        mMinutes = minute + second / 60.0f;

        mHour = hour + mMinutes / 60.0f;

        mChanged = true;

    }
}   

笔记 77 | Launcher表盘时间部件工具类(时,分,秒)