Android 8.1 Launcher3实现动态指针时钟

Android 8.1 Launcher3实现动态指针时钟

本文主要实现功能,可能有不合理的地方

首先创建一个实现功能的工具里,直接上代码:

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.util.LogUtil;


public class DeskClockUtil {

    private OnDeskClockIconChangeListener mListener;
    private ItemInfo mItemInfo;

    private boolean mIsResume;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 100) {
                Message msg1 = new Message();
                msg1.what = 100;
                msg1.obj = msg.obj;
                mHandler.sendMessageDelayed(msg1, 60000);
                if (mListener != null && mItemInfo != null) {
                    mListener.onChange(IconUtil.getDeskClockIcon((Context) msg.obj), mItemInfo);
                }
            }
        }
    };

    private static DeskClockUtil sInstance;

    private DeskClockUtil() {
    }

    public static DeskClockUtil getInstance() {
        if (sInstance == null) {
            sInstance = new DeskClockUtil();
        }
        return sInstance;
    }

    private void refresh(Context context) {
        if (mListener != null && mItemInfo != null) {
            mListener.onChange(IconUtil.getDeskClockIcon(context), mItemInfo);
        }
        if (mHandler.hasMessages(100)) {
            mHandler.removeMessages(100);
        }
        Message msg = new Message();
        msg.what = 100;
        msg.obj = context;
        mHandler.sendMessageDelayed(msg,
                1000 * (60 - Integer.parseInt(DateUtils.getCurrentSecond())));
    }

    public void onResume(Context context) {
        mIsResume = true;
        refresh(context);
    }

    public void onPause() {
        mIsResume = false;
        mHandler.removeMessages(100);
    }

    public void setListener(OnDeskClockIconChangeListener listener, ItemInfo info, Context context) {
        if (!(info instanceof ShortcutInfo)) {
            return;
        }
        String pkg = null;
        if (info.getIntent() != null && info.getIntent().getComponent() != null) {
            pkg = info.getIntent().getComponent().getPackageName();
        }
        if (!"com.android.deskclock".equals(pkg) || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
            return;
        }
        mListener = listener;
        mItemInfo = info;
        if (mIsResume) {
            refresh(context);
        }
    }

    public interface OnDeskClockIconChangeListener {

        void onChange(Bitmap icon, ItemInfo info);

    }

}

画出动态时钟

import android.content.Context;
import android.graphics.*;
import com.android.launcher3.R;

public class IconUtil {

    private static final String TAG = "IconUtil";

    private static Bitmap getBitmap(Context context, int res) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_4444;
        return BitmapFactory.decodeResource(context.getResources(), res, options);
    }

    public static Bitmap getDeskClockIcon(Context context) {
        // 添加一个带表盘的背景图
        Bitmap empty = getBitmap(context, R.drawable.icon_time);
        int x = empty.getWidth();
        int y = empty.getHeight();
        Bitmap deskClock = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(deskClock);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawBitmap(empty, 0, 0, paint);
        //设置圆角
        paint.setStrokeCap(Paint.Cap.ROUND);

        paint.setStrokeWidth(5);
        paint.setColor(context.getResources().getColor(R.color.deskclock_time));
        // 时针的长度
        int radius = 35;
        // 圆心的x y 坐标
        int cx = x / 2;
        int cy = y / 2;

        int hour = Integer.parseInt(DateUtils.getCurrentHour());
        int min = Integer.parseInt(DateUtils.getCurrentMin());
        //时针的角度,这里是整点的角度。因为0°是从3点开始,所以这里减90°,从9点开始计算角度
        int drgeeHour = hour * 30 - 90;
        if (drgeeHour < 0) {
            drgeeHour += 360;
        }
        // 加上时针在两个整点之间的角度,一分钟在分针上是6°,在时针上是min * 6 / 12
        drgeeHour += min * 6 / 12;
        //时针 针尖的x y坐标,相当于已知圆心坐标和半径,求圆上任意一点的坐标
        int xHour = (int) (cx + radius * Math.cos(drgeeHour * 3.14 / 180));
        int yHour = (int) (cy + radius * Math.sin(drgeeHour * 3.14 / 180));
        canvas.drawLine(xHour, yHour, cx, cy, paint);
        //分针的长度
        radius = 45;
        paint.setStrokeWidth(3);
        paint.setColor(Color.RED);
        //分针的角度
        int drgeeMin = min * 6 - 90;
        if (drgeeMin < 0) {
            drgeeMin += 360;
        }
        //分针 针尖的x y坐标
        int x1 = (int) (cx + radius * Math.cos(drgeeMin * Math.PI / 180));
        int y1 = (int) (cy + radius * Math.sin(drgeeMin * Math.PI / 180));
        canvas.drawLine(x1, y1, cx, cy, paint);
        return deskClock;
    }

}

时间工具类

import java.text.SimpleDateFormat;

public class DateUtils {

    public static String getCurrentDay() {
        SimpleDateFormat format = new SimpleDateFormat("dd");
        Long t = new Long(System.currentTimeMillis());
        String d = format.format(t);
        return d;
    }

    public static String getCurrentSecond() {
        SimpleDateFormat format = new SimpleDateFormat("ss");
        Long t = new Long(System.currentTimeMillis());
        String d = format.format(t);
        return d;
    }

    public static String getCurrentMin() {
        SimpleDateFormat format = new SimpleDateFormat("mm");
        Long t = new Long(System.currentTimeMillis());
        String d = format.format(t);
        return d;
    }

    public static String getCurrentHour() {
        SimpleDateFormat format = new SimpleDateFormat("HH");
        Long t = new Long(System.currentTimeMillis());
        String d = format.format(t);
        return d;
    }


}

下面就比较简单了,我是在BubbleTextView.java中添加listener,我这里偷懒了,应该给时钟单独创建一个view,继承BubbleTextView。

private void applyIconAndLabel(Bitmap icon, ItemInfo info) {
        /*  begin */
        setDeskClockIcon(info);
        /*  end */
        applyIcon(icon, info);
        setText(info.title);
        if (info.contentDescription != null) {
            setContentDescription(info.isDisabled()
                    ? getContext().getString(R.string.disabled_app_label, info.contentDescription)
                    : info.contentDescription);
        }
    }

    private void setDeskClockIcon(ItemInfo info) {
        DeskClockUtil.getInstance().setListener(new DeskClockUtil.OnDeskClockIconChangeListener() {
            @Override
            public void onChange(Bitmap icon, ItemInfo info) {
                applyIcon(icon, info);
            }
        }, info, getContext());
    }

    private void applyIcon(Bitmap icon, ItemInfo info) {
        FastBitmapDrawable iconDrawable = DrawableFactory.get(getContext()).newIcon(icon, info);
        iconDrawable.setIsDisabled(info.isDisabled());
        setIcon(iconDrawable);
    }

在Launcher.java的onResume()和onPause()中分别开始和暂停

@Override
    protected void onResume() {
      ......

        /* begin */
        DeskClockUtil.getInstance().onResume(this);
        /*  end */

        if (mLauncherCallbacks != null) {
            mLauncherCallbacks.onResume();
        }

    }
@Override
    protected void onPause() {
        // Ensure that items added to Launcher are queued until Launcher returns
        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_ACTIVITY_PAUSED);

        super.onPause();
        mPaused = true;
        mDragController.cancelDrag();
        mDragController.resetLastGestureUpTime();

        // We call onHide() aggressively. The custom content callbacks should be able to
        // debounce excess onHide calls.
        if (mWorkspace.getCustomContentCallbacks() != null) {
            mWorkspace.getCustomContentCallbacks().onHide();
        }

        if (mLauncherCallbacks != null) {
            mLauncherCallbacks.onPause();
        }
        /*  begin */
        DeskClockUtil.getInstance().onPause();
        /*  end */
    }

这样就可以了,如果想要加秒针,在IconUtil中再把秒针画出来就行。
还有日历的动态图标也可以用同样的方法实现

你可能感兴趣的:(Android)