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

21 篇文章 0 订阅

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;

    }
}   

坐标

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值