Android 8.1 Launcher3 Realizes Dynamic Pointer Clock Function
- 2021-09-16 07:58:54
- OfStack
This article mainly realizes the function, may have the unreasonable place
First of all, create a tool to realize the function, and directly add the code:
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);
}
}
Draw a dynamic clock
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) {
// Add 1 Background picture with dial
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);
// Set fillet
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(5);
paint.setColor(context.getResources().getColor(R.color.deskclock_time));
// The length of the hour hand
int radius = 35;
// Center of a circle x y Coordinates
int cx = x / 2;
int cy = y / 2;
int hour = Integer.parseInt(DateUtils.getCurrentHour());
int min = Integer.parseInt(DateUtils.getCurrentMin());
// The angle of the hour hand, here is the angle of the hour. Because 0 ° is derived from 3 Point, so minus here 90 °, from 9 Calculate the angle from the point
int drgeeHour = hour * 30 - 90;
if (drgeeHour < 0) {
drgeeHour += 360;
}
// Plus the angle of the hour hand between two hourly points, 1 Minutes on the minute hand is 6 °, on the hour hand is min * 6 / 12
drgeeHour += min * 6 / 12;
// Hour hand Needle-tip x y Coordinates, equivalent to the known center coordinates and radius of the circle, find any on the circle 1 Coordinates of points
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);
// The length of the minute hand
radius = 45;
paint.setStrokeWidth(3);
paint.setColor(Color.RED);
// Angle of the minute hand
int drgeeMin = min * 6 - 90;
if (drgeeMin < 0) {
drgeeMin += 360;
}
// Minute hand Needle-tip x y Coordinates
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;
}
}
Time tool class
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;
}
}
The following is relatively simple. I added listener to BubbleTextView. java. I am lazy here. I should create an view for the clock and inherit 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);
}
Start and pause in onResume () and onPause () of Launcher. java, respectively
@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 */
}
That's it. If you want to add a second hand, just draw the second hand in IconUtil.
There are also dynamic icons of calendars that can be implemented in the same way
Summarize