美文网首页
笔记 77 | Launcher表盘时间部件工具类(时,分,秒)

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

作者: 项勇 | 来源:发表于2018-07-05 18:53 被阅读12次

    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表盘时间部件工具类(时,分,秒)

          本文链接:https://www.haomeiwen.com/subject/cixmuftx.html