在launcher中,长按桌面会触发很多种行为。其分类包括:1、空白桌面;2、桌面内容(文件夹、快捷方式、文件夹等);3、桌面既有控件(左右两个屏幕切换按钮,all app list按钮)等;因此我们很容易理解Launcher.java文件中onLongClick函数的行为:
public boolean onLongClick(View v) {
switch (v.getId()) {
case R.id.previous_screen:
if (!isAllAppsVisible()) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
}
return true;
case R.id.next_screen:
if (!isAllAppsVisible()) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
}
return true;
case R.id.all_apps_button:
if (!isAllAppsVisible()) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
}
return true;
}
//当不是跳转到别的屏幕,或者不是all_app_button被长按时,继续下面的处理。
if (isWorkspaceLocked()) {
return false;
}
if (!(v instanceof CellLayout)) {
v = (View) v.getParent();
}
CellLayout.CellInfo cellInfo = (CellLayout.CellInfo) v.getTag();
// This happens when long clicking an item with the dpad/trackball
if (cellInfo == null) {
return true;
}
if (mWorkspace.allowLongPress()) {
if (cellInfo.cell == null) { //说明长按的地方是空白的
if (cellInfo.valid) {
// User long pressed on empty space
mWorkspace.setAllowLongPress(false);
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showAddDialog(cellInfo); //长按的地方有效,则显示一个选择dialog
}
} else {//非空白
if (!(cellInfo.cell instanceof Folder)) { //不是文件
// User long pressed on an item
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
mWorkspace.startDrag(cellInfo);
}
}
}
return true;
}
showAddDialog(cellInfo)继续调用showDialog(DIALOG_CREATE_SHORTCUT);此时可以搜索下,发现Launcher.java覆写了onCreateDialog方法:
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_CREATE_SHORTCUT:
return new CreateShortcut().createDialog();
case DIALOG_RENAME_FOLDER:
return new RenameFolder().createDialog();
}
return super.onCreateDialog(id);
}
可以看到,最终调用的是内部类CreateShortcut的createDialog()方法来创建一个选择 Dialog。
继续分析createDialog()方法,可以看到它初始化了一个AddAdapter:
mAdapter = new AddAdapter(Launcher.this);
跟进去发现,这就是Dialog上显示的菜单的初始化位置:
public AddAdapter(Launcher launcher) {
super();
mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Create default actions
Resources res = launcher.getResources();
mItems.add(new ListItem(res, R.string.group_shortcuts,
R.drawable.ic_launcher_shortcut, ITEM_SHORTCUT)); //shortcut
mItems.add(new ListItem(res, R.string.group_widgets,
R.drawable.ic_launcher_appwidget, ITEM_APPWIDGET));//widget
mItems.add(new ListItem(res, R.string.group_live_folders,
R.drawable.ic_launcher_folder, ITEM_LIVE_FOLDER));//folder
mItems.add(new ListItem(res, R.string.group_wallpapers,
R.drawable.ic_launcher_wallpaper, ITEM_WALLPAPER));//wallpaper
}
这样,选择Dialog就出现了,下面是它的响应函数,同理,在CreateShortcut内部类中实现了onClick()函数:
public void onClick(DialogInterface dialog, int which) {
Resources res = getResources();
cleanup();
//CR 249200 Modify start
isClicked = true;
//CR 249200 Modify end
switch (which) {
case AddAdapter.ITEM_SHORTCUT: { //shortcut处理
// Insert extra item to handle picking application
pickShortcut();
break;
}
case AddAdapter.ITEM_APPWIDGET: { //widget处理
int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// start the pick activity
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
break;
}
case AddAdapter.ITEM_LIVE_FOLDER: { //文件夹处理
// Insert extra item to handle inserting folder
Bundle bundle = new Bundle();
ArrayList<String> shortcutNames = new ArrayList<String>();
shortcutNames.add(res.getString(R.string.group_folder));
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
ArrayList<ShortcutIconResource> shortcutIcons =
new ArrayList<ShortcutIconResource>();
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
R.drawable.ic_launcher_folder));
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT,
new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
pickIntent.putExtra(Intent.EXTRA_TITLE,
getText(R.string.title_select_live_folder));
pickIntent.putExtras(bundle);
startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
break;
}
case AddAdapter.ITEM_WALLPAPER: { //选择壁纸
startWallpaper();
break;
}
}
}
如上,长按的动作就分析完了,当onClick()函数接收到不同的动作后,会分派到不同的函数去处理。