Android 8.1 Launcher3實現(xiàn)動態(tài)指針時鐘功能
本文主要實現(xiàn)功能,可能有不合理的地方
首先創(chuàng)建一個實現(xiàn)功能的工具里,直接上代碼:
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);
}
}
畫出動態(tài)時鐘
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);
//設(shè)置圓角
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(5);
paint.setColor(context.getResources().getColor(R.color.deskclock_time));
// 時針的長度
int radius = 35;
// 圓心的x y 坐標(biāo)
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坐標(biāo),相當(dāng)于已知圓心坐標(biāo)和半徑,求圓上任意一點的坐標(biāo)
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坐標(biāo)
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,我這里偷懶了,應(yīng)該給時鐘單獨創(chuàng)建一個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中再把秒針畫出來就行。
還有日歷的動態(tài)圖標(biāo)也可以用同樣的方法實現(xiàn)
總結(jié)
以上所述是小編給大家介紹的Android 8.1 Launcher3實現(xiàn)動態(tài)指針時鐘功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Android RecyclerView緩存復(fù)用原理解析
RecyclerView是Android一個更強(qiáng)大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法2022-11-11
Android利用CountDownTimer實現(xiàn)驗證碼倒計時效果實例
這篇文章主要給大家介紹了關(guān)于Android如何利用CountDownTimer實現(xiàn)驗證碼倒計時效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
Android如何讓W(xué)ebView中的HTML5頁面實現(xiàn)視頻全屏播放
最近在工作遇到一個需求,需要讓W(xué)ebView中的HTML5頁面實現(xiàn)視頻全屏播放的效果,通過查找相關(guān)的資料終于找到了解決的方法,所以想著分享給大家,所以本文介紹了關(guān)于Android如何讓W(xué)ebView中的HTML5頁面實現(xiàn)視頻全屏播放的相關(guān)資料,需要的朋友可以參考學(xué)習(xí)。2017-04-04
Android官方的側(cè)滑控件DrawerLayout的示例代碼
這篇文章主要介紹了Android官方的側(cè)滑控件DrawerLayout的示例代碼,非常具有實用價值,需要的朋友可以參考下2017-09-09
android中一些特殊字符(如:←↑→↓等箭頭符號)的Unicode碼值
這篇文章主要介紹了android中一些特殊字符(如:←↑→↓等箭頭符號)的Unicode碼值,需要的朋友可以參考下2017-03-03
Android實現(xiàn)RecyclerView下拉刷新效果
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)RecyclerView下拉刷新效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07

