当点击桌面的Launcher图标的时候,执行的是Launcher.java中的onClick()方法,我们来看看这个方法。
public void onClick(View v) {
// Make sure that rogue clicks don't get through while allapps is launching, or after the
// view has detached (it's possible for this to happen if the view is removed mid touch).
if (v.getWindowToken() == null) {
return;
}
if (!mWorkspace.isFinishedSwitchingState()) {
return;
}
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// Open shortcut
final Intent intent = ((ShortcutInfo) tag).intent;
int[] pos = new int[2];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[0], pos[1],
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
boolean success = startActivitySafely(v, intent, tag);
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
mWaitingForResume.setStayPressed(true);
}
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) v;
handleFolderClick(fi);
}
} else if (v == mAllAppsButton) {
if (isAllAppsVisible()) {
showWorkspace(true);
} else {
onClickAllAppsButton(v);
}
}
}
需要重点关注的代码是:
// 得到启动该应用的intent
final Intent intent = ((ShortcutInfo) tag).intent;
int[] pos = new int[2];
// 得到点击的桌面应用icon在屏幕的位置
v.getLocationOnScreen(pos);
// 在该应用的intent中设置桌面应用icon的左上角坐标(pos[0], pos[1])
// 和右下角坐标(pos[0] + v.getWidth(), pos[1] + v.getHeight())
intent.setSourceBounds(new Rect(pos[0], pos[1],
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
// 启动这个应用
boolean success = startActivitySafely(v, intent, tag);
这样其实我们在Activity中可以通过Intent.getSourceBounds()方法得到我们点击的应用图标的位置坐标。即通过Intent.getSourceBounds()方法可以获取到Shortcut在Launcher中的坐标信息。
这样我们就可以做一些桌面的动效,例如,目前市面上好多的工具类软件都实现了很有意思的交互方式,当用户点击Launcher上应用快捷方式icon时,图标变成了一个风扇在旋转。
它其实使用到一个障眼法,当点击快捷桌面的icon的时候,可以启动一个透明的Activity,在这个Activity中可以通过Intent.getSourceBounds()拿到点击的icon的位置,这样我们就可以在这个位置上覆盖一个风扇旋转动画,这个风扇刚好把应用图标覆盖了,所以给用户的感觉就是点击这个快捷方式图标之后,这个快捷方式图标变成一个旋转的风扇。实质获取桌面icon的位置是关键。
参考文章:【Android开发技巧】 - 如何获取应用Shortcut在Launcher坐标信息