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

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*/@RemoteViewpublic 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;    }}   

原文发布于微信公众号 - 项勇(xiangy_life)

原文发表时间:2018-07-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jack的Android之旅

模仿企鹅FM播放主页面滑动动态改变各视图的大小

国庆的一个任务就是把自己之前写的代码搬到博客。这次给各位带来的是通过滑动来动态改变各个View的大小进而达到企鹅FM播放页面的滑动效果(仅仅是滑动效果),老规矩...

1002
来自专栏潇涧技术专栏

Android Heroes Reading Notes 2

《Android群英传》读书笔记 (2) 第三章 控件架构与自定义控件详解 + 第四章 ListView使用技巧 + 第五章 Scroll分析

931
来自专栏程序员叨叨叨

【Android】手把手教你上滑解锁的效果

最近,公司开发的APP中要实现类似上滑解锁效果的推荐页,捣腾了两天,基本实现了效果,附效果图如上。接下来和大家聊聊如何实现这样的效果。

4732
来自专栏Android开发与分享

【Android】在任意位置弹出PopupWindow

49410
来自专栏Android开发指南

7.侧滑、ViewDragHelper、属性动画

3125
来自专栏青蛙要fly的专栏

项目需求讨论:截图—涂鸦—分享

这个也是具体项目中遇到的项目需求:需要在一个特定的界面中(都是图表和各种数据,可能需求分享给别人,告诉别人这个数据怎么怎么,这个图表怎么怎么) 所以给我们开发的...

1404
来自专栏学海无涯

Android开发之自定义View(二)

在 Android开发之自定义View(一)中,讲解了最复杂的一种自定义View,本次将剩下的两种讲完~~~ go,go,go 继承原有的控件,在原有控件基础上...

3338
来自专栏向治洪

android 自定义gallerey并实现预览功能

自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果。的确Horizon...

2765
来自专栏Android学习之路

ViewDragHelper使用笔记及侧滑菜单实践

3036
来自专栏Android Note

Android-水平和垂直方向都可滑动的RecycleView

1762

扫码关注云+社区

领取腾讯云代金券