android自定义Folder
2012-10-20 10:44
127 查看
android 4.0自定义Folder--UFolder
===============
LauncherSettings & Favorites 增加
static final int ITEM_TYPE_UFOLDER = 5;
用以区分普通Folder
1.在各个地方针对ufolder进行判断,进行定制
1)//加载default_worksapce.xml,并记录到数据库
LauncherProvider.java
2) 加载ufolder
LauncherModel.java
3)定义 ufloder 图标
Launcher.java
Workspace.java
===============
2.ufolder 的其他额外功能
1)当自定义的folder,所包含的内容<=1时,不从Launcher界面删除,也不删除数据库的记录
Folder.java
2).ufolder onDrop 时,不能删除。
在workspace中移动ufolder时,不显示DeleteDropTarget。就是那个 (X Remove) 图标
DeleteDropTarget extends ButtonDropTarget
3).监控app install事件,ufolder 自动添加刚安装的app
Lancher.java
Workspace.java
===================
其他有关Folder的记录:
1.FolderIcon.java
computePreviewItemDrawingParams()
计算Folder上预览图标的参数,在dispatchDraw()中绘制,默认画三个。
2.两个shortcut拖到一起时会形成个folder
Workspace.java
createUserFolderIfNecessary();
在onDrogOver()中
===============
LauncherSettings & Favorites 增加
static final int ITEM_TYPE_UFOLDER = 5;
用以区分普通Folder
1.在各个地方针对ufolder进行判断,进行定制
1)//加载default_worksapce.xml,并记录到数据库
LauncherProvider.java
private long addUFolder(SQLiteDatabase db, ContentValues values) { values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_UFOLDER); values.put(Favorites.SPANX, 1); values.put(Favorites.SPANY, 1); long id = generateNewId(); values.put(Favorites._ID, id); if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) <= 0) { return -1; } else { return id; } } private int loadCustomFolder(SQLiteDatabase db, int workspaceResourceId) { ... if (TAG_UFOLDER.equals(name)) { String title; int titleResId = a.getResourceId(R.styleable.Favorite_title, -1); if (titleResId != -1) { title = mContext.getResources().getString(titleResId); } else { title = mContext.getResources().getString(R.string.folder_name); } values.put(LauncherSettings.Favorites.TITLE, title); long folderId = addUFolder(db, values); added = folderId >= 0; ArrayList<Long> folderItems = new ArrayList<Long>(); values.clear(); values.put(LauncherSettings.Favorites.CONTAINER, folderId); // get the download app list getCustomAppList(); for (AppInfo appInfo : appList) { long id = addCustumAppShortcut(db, values, packageManager, intent, appInfo); if (id >= 0) { folderItems.add(id); } } // We can only have folders with >= 2 items, so we need to remove the // folder and clean up if less than 2 items were included, or some // failed to add, and less than 2 were actually added //if (folderItems.size() < 2 && folderId >= 0) { // We just delete the folder and any items that made it /*deleteId(db, folderId); if (folderItems.size() > 0) { deleteId(db, folderItems.get(0)); } added = false;*/ //} } ..... }
//获取系统下载的app列表 private ArrayList<AppInfo> appList = new ArrayList<AppInfo>(); private void getCustomAppList() { List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES); for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if ((packageInfo.applicationInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) == 0) { ActivityInfo aInfo; try { aInfo = packageInfo.activities[0]; } catch (Exception e) { Log.w(TAG, "Got exception for getCustomAppList", e); continue; } AppInfo tmpInfo = new AppInfo(); tmpInfo.appName = packageInfo.applicationInfo.loadLabel(mContext.getPackageManager()).toString(); tmpInfo.appIcon = packageInfo.applicationInfo.loadIcon(mContext.getPackageManager()); tmpInfo.packageName = packageInfo.packageName; tmpInfo.versionName = packageInfo.versionName; tmpInfo.versionCode = packageInfo.versionCode; if (aInfo != null) tmpInfo.className = aInfo.name; // Only display the non-system app info appList.add(tmpInfo); } } } //把列表插入数据库,LauncherModel loadWorkspace 就能加载了 private long addCustumAppShortcut(SQLiteDatabase db, ContentValues values, PackageManager packageManager, Intent intent, AppInfo appInfo) { long id = -1; ActivityInfo info; String packageName = appInfo.packageName; String className = appInfo.className; try { ComponentName cn; try { cn = new ComponentName(packageName, className); info = packageManager.getActivityInfo(cn, 0); } catch (PackageManager.NameNotFoundException nnfe) { String[] packages = packageManager.currentToCanonicalPackageNames( new String[] { packageName }); cn = new ComponentName(packages[0], className); info = packageManager.getActivityInfo(cn, 0); } id = generateNewId(); intent.setComponent(cn); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); values.put(Favorites.INTENT, intent.toUri(0)); values.put(Favorites.TITLE, appInfo.appName); values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION); values.put(Favorites.SPANX, 1); values.put(Favorites.SPANY, 1); values.put(Favorites._ID, generateNewId()); if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) { return -1; } } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Unable to add favorite: " + packageName + "/" + className, e); } return id; }
2) 加载ufolder
LauncherModel.java
private void loadWorkspace() { ..... while (!mStopped && c.moveToNext()) { try { int itemType = c.getInt(itemTypeIndex); switch (itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: ... case LauncherSettings.Favorites.ITEM_TYPE_UFOLDER: isUFolder = true; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: id = c.getLong(idIndex); FolderInfo folderInfo = findOrMakeFolder(sFolders, id); //设置 ufolder 的itemType // 这里用了个boolean isUFolder 判断,因为好像只有case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: // 才能生成folder.(应该会后更好的解决方法) if (isUFolder) folderInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_UFOLDER; folderInfo.title = c.getString(titleIndex); folderInfo.id = id; container = c.getInt(containerIndex); folderInfo.container = container; folderInfo.screen = c.getInt(screenIndex); folderInfo.cellX = c.getInt(cellXIndex); folderInfo.cellY = c.getInt(cellYIndex); // check & update map of what's occupied if (!checkItemPlacement(occupied, folderInfo)) { break; } switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: case LauncherSettings.Favorites.CONTAINER_HOTSEAT: sWorkspaceItems.add(folderInfo); break; } sItemsIdMap.put(folderInfo.id, folderInfo); sFolders.put(folderInfo.id, folderInfo); isUFolder = false; break; ........ } }
3)定义 ufloder 图标
Launcher.java
public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) { setLoadOnResume(); final Workspace workspace = mWorkspace; for (int i=start; i<end; i++) { final ItemInfo item = shortcuts.get(i); // Short circuit if we are loading dock items for a configuration which has no dock if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT && mHotseat == null) { continue; } switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: View shortcut = createShortcut((ShortcutInfo)item); workspace.addInScreen(shortcut, item.container, item.screen, item.cellX, item.cellY, 1, 1, false); break; case LauncherSettings.Favorites.ITEM_TYPE_UFOLDER: //ufolder icon layout ufolder_icon.xml FolderIcon newUFolder = FolderIcon.fromXml(R.layout.ufolder_icon, this, (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()), (FolderInfo) item, mIconCache); // 就是通过这在workspace中显示folder的 workspace.addInScreen(newUFolder, item.container, item.screen, item.cellX, item.cellY, 1, 1, false); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()), (FolderInfo) item, mIconCache); workspace.addInScreen(newFolder, item.container, item.screen, item.cellX, item.cellY, 1, 1, false); break; } } workspace.requestLayout(); }
Workspace.java
private void onDropExternal(final int[] touchXY, final Object dragInfo, final CellLayout cellLayout, boolean insertAtFirst, DragObject d) { switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: if (info.container == NO_ID && info instanceof ApplicationInfo) { // Came from all apps -- make a copy info = new ShortcutInfo((ApplicationInfo) info); } view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info); break; case LauncherSettings.Favorites.ITEM_TYPE_UFOLDER: view = FolderIcon.fromXml(R.layout.ufolder_icon, mLauncher, cellLayout, (FolderInfo) info, mIconCache); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, cellLayout, (FolderInfo) info, mIconCache); break; default: throw new IllegalStateException("Unknown item type: " + info.itemType); } }
===============
2.ufolder 的其他额外功能
1)当自定义的folder,所包含的内容<=1时,不从Launcher界面删除,也不删除数据库的记录
Folder.java
private void replaceFolderWithFinalItem() { if (mInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_UFOLDER) return; ItemInfo finalItem = null; if (getItemCount() == 1) { finalItem = mInfo.contents.get(0); } // Remove the folder completely CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen); cellLayout.removeView(mFolderIcon); if (mFolderIcon instanceof DropTarget) { mDragController.removeDropTarget((DropTarget) mFolderIcon); } mLauncher.removeFolder(mInfo); if (finalItem != null) { LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, mInfo.screen, mInfo.cellX, mInfo.cellY); } LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); // Add the last remaining child to the workspace in place of the folder if (finalItem != null) { View child = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) finalItem); mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen, mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY); } }
2).ufolder onDrop 时,不能删除。
在workspace中移动ufolder时,不显示DeleteDropTarget。就是那个 (X Remove) 图标
DeleteDropTarget extends ButtonDropTarget
public void onDragStart(DragSource source, Object info, int dragAction) { boolean isVisible = true; boolean isUninstall = false; if (info instanceof FolderInfo) { FolderInfo folderInfo = (FolderInfo) info; if (folderInfo.itemType == 5) { isVisible = false; } } ...... } // 删除对应的DragObject private void completeDrop(DragObject d) { ItemInfo item = (ItemInfo) d.dragInfo; if (isAllAppsApplication(d.dragSource, item)) { // Uninstall the application if it is being dragged from AppsCustomize mLauncher.startApplicationUninstallActivity((ApplicationInfo) item); } else if (isWorkspaceOrFolderApplication(d)) { LauncherModel.deleteItemFromDatabase(mLauncher, item); } else if (isWorkspaceFolder(d)) { // Remove the folder from the workspace and delete the contents from launcher model FolderInfo folderInfo = (FolderInfo) item; mLauncher.removeFolder(folderInfo); LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo); } else if (isWorkspaceOrFolderWidget(d)) { // Remove the widget from the workspace mLauncher.removeAppWidget((LauncherAppWidgetInfo) item); LauncherModel.deleteItemFromDatabase(mLauncher, item); final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item; final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost(); if (appWidgetHost != null) { // Deleting an app widget ID is a void call but writes to disk before returning // to the caller... new Thread("deleteAppWidgetId") { public void run() { appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId); } }.start(); } } }
3).监控app install事件,ufolder 自动添加刚安装的app
Lancher.java
/** * A package was installed. * * Implementation of the method from LauncherModel.Callbacks. */ public void bindAppsAdded(ArrayList<ApplicationInfo> apps) { setLoadOnResume(); removeDialog(DIALOG_CREATE_SHORTCUT); mWorkspace.addItems(apps); if (mAppsCustomizeContent != null) { mAppsCustomizeContent.addApps(apps); } }
Workspace.java
void addItems(final ArrayList<ApplicationInfo> apps) { final ArrayList<ShortcutInfo> addContentInfo = new ArrayList<ShortcutInfo>(); final int appCount = apps.size(); for (int i = 0; i < appCount; i++) { addContentInfo.add(apps.get(i).makeShortcut()); } ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts(); for (final CellLayout layoutParent: cellLayouts) { final ViewGroup layout = layoutParent.getChildrenLayout(); // Avoid ANRs by treating each screen separately post(new Runnable() { public void run() { final ArrayList<View> childrenToAdd = new ArrayList<View>(); childrenToAdd.clear(); int childCount = layout.getChildCount(); for (int j = 0; j < childCount; j++) { final View view = layout.getChildAt(j); Object tag = view.getTag(); if (tag instanceof FolderInfo) { final FolderInfo info = (FolderInfo) tag; if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_UFOLDER) { for (ShortcutInfo appInfo : addContentInfo) { // add in folder and insert data to database info.add(appInfo); } } } } } }); } }
===================
其他有关Folder的记录:
1.FolderIcon.java
computePreviewItemDrawingParams()
计算Folder上预览图标的参数,在dispatchDraw()中绘制,默认画三个。
2.两个shortcut拖到一起时会形成个folder
Workspace.java
createUserFolderIfNecessary();
在onDrogOver()中
if (userFolderPending && dragOverView != mLastDragOverView) { mFolderCreationAlarm.setOnAlarmListener(new FolderCreationAlarmListener(mDragTargetLayout, mTargetCell[0], mTargetCell[1])); mFolderCreationAlarm.setAlarm(FOLDER_CREATION_TIMEOUT); } public void onAlarm(Alarm alarm) { if (mDragFolderRingAnimator == null) { mDragFolderRingAnimator = new FolderRingAnimator(mLauncher, null); } mDragFolderRingAnimator.setCell(cellX, cellY); mDragFolderRingAnimator.setCellLayout(layout); mDragFolderRingAnimator.animateToAcceptState(); Resources res = mLauncher.getResources(); //生成folder的动画 FolderRingAnimator.sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo); FolderRingAnimator.sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo); layout.showFolderAccept(mDragFolderRingAnimator); mCreateUserFolderOnDrop = true; }
相关文章推荐
- android自定义组合控件,参考Launcher中FolderIcon构成,欢迎拍砖。
- android 自定义Preferecne布局
- Android自定义类似ProgressDialog效果的Dialog
- Android中自定义View(1)
- Android自定义ViewGroup打造各种风格的SlidingMenu
- Android开发中自定义视图
- Android 发送系统广播与自定义广播
- Android自定义View之电池电量显示
- Android进阶——自定义View之扩展系统Dialog
- Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)
- Android 自定义标题栏
- Android-Andriod studio自定义那些事
- Android自定义view系列之99.99%实现QQ侧滑删除效果实例代码详解
- Android自定义View图片按Path运动和旋转
- android intent 及自定义消息传递
- Android自定义裁剪图片
- Android中如何使用自定义view 自定义控件属性及动态自定义控件
- Android自定义View——仿vivo i管家病毒扫描动画效果
- android自定义ImageView仿图片上传示例
- Android实现自定义自画的图片的Button