android 6.0 Launcher3 去掉抽屉式,显示所有 app
效果图
修改思路
1、去除 allAppsButton,调整 HotSeat 布局,禁止增删,禁止生成 Folder
2、将 AllAppsContainerView 中的图标加载到 Workspace
3、去除 Workspace 图标长按删除选项
上代码
1、增加全局控制开关,方便客户选择是否需要去掉抽屉界面。
Launcher3\src\com\android\launcher3\LauncherAppState.java
//cczheng add check is need allappbuttonpublic static boolean isDisableAllApps() { if (sContext != null) { return Settings.System.getInt(sContext.getContentResolver(), "sys.launcher3.is_full_app", 1) == 1; } return true; }
在 LauncherAppState 中添加获取变量的值,对应的值修改可以在 Setting 中通过增加 SwitchPreference 开关或者在 workSpace 长按显示的 view 中增加。
2、取消占位,去除 allAppsButton 按钮
packages\apps\Launcher3\src\com\android\launcher3\Hotseat.java
取消占位
public boolean isAllAppsButtonRank(int rank) { //cczheng add cancel allAppsButton location log("isAllAppsButtonRank=="+rank + " mAllAppsButtonRank="+mAllAppsButtonRank); if (LauncherAppState.isDisableAllApps()) { return false; } return rank == mAllAppsButtonRank; }
去除 allAppsButton 按钮
void resetLayout() { mContent.removeAllViewsInLayout(); // cczheng add juge is need add allAppsButton S if (!LauncherAppState.isDisableAllApps()) { Context context = getContext(); LayoutInflater inflater = LayoutInflater.from(context); TextView allAppsButton = (TextView) inflater.inflate(R.layout.all_apps_button, mContent, false); Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon); mLauncher.resizeIconDrawable(d); allAppsButton.setCompoundDrawables(null, d, null, null); allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label)); allAppsButton.setOnKeyListener(new HotseatIconKeyEventListener()); if (mLauncher != null) { mLauncher.setAllAppsButton(allAppsButton); allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener()); allAppsButton.setOnClickListener(mLauncher); allAppsButton.setOnLongClickListener(mLauncher); allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler); } // Note: We do this to ensure that the hotseat is always laid out in the orientation of // the hotseat in order regardless of which orientation they were added int x = getCellXFromOrder(mAllAppsButtonRank); int y = getCellYFromOrder(mAllAppsButtonRank); CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x,y,1,1); lp.canReorder = false; mContent.addViewToCellLayout(allAppsButton, -1, allAppsButton.getId(), lp, true); }//E }
HotSeat 增加背景
@Override protected void onFinishInflate() { super.onFinishInflate(); DeviceProfile grid = mLauncher.getDeviceProfile(); mAllAppsButtonRank = grid.inv.hotseatAllAppsRank; mContent = (CellLayout) findViewById(R.id.layout); if (grid.isLandscape && !grid.isLargeTablet) { mContent.setGridSize(1, (int) grid.inv.numHotseatIcons); } else { mContent.setGridSize((int) grid.inv.numHotseatIcons, 1); } mContent.setIsHotseat(true); Log.i(TAG, "onFinishInflate,(int) grid.numHotseatIcons: "); //cczheng add hotseat bg [s] if (LauncherAppState.isDisableAllApps()) { setBackgroundResource(R.drawable.hotseat_bg); }//E resetLayout(); }
hotseat_bg.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <stroke android:width="0.1dp" android:color="#ffffffff" /> <solid android:color="#50000000" /> <corners android:radius="10dp" /></shape>
3、HotSeat 区域图标大小调整
Launcher3\src\com\android\launcher3\DeviceProfile.java
区域大小调整
public void layout(Launcher launcher) { FrameLayout.LayoutParams lp; boolean hasVerticalBarLayout = isVerticalBarLayout(); final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources()); .... else { // For phones, layout the hotseat without any bottom margin // to ensure that we have space for the folders /*lp.gravity = Gravity.BOTTOM; lp.width = LayoutParams.MATCH_PARENT; lp.height = hotseatBarHeightPx; hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 2 * edgeMarginPx, 0);*/ //cczheng add if change hotseat default size S if (LauncherAppState.isDisableAllApps()) { lp.gravity = Gravity.BOTTOM | Gravity.CENTER; lp.width = 600; lp.height = 120; }else{//E lp.gravity = Gravity.BOTTOM; lp.width = LayoutParams.MATCH_PARENT; lp.height = hotseatBarHeightPx; hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 2 * edgeMarginPx, 0); } } hotseat.setLayoutParams(lp);...}
图标大小调整
Launcher3\src\com\android\launcher3\CellLayout.java
public float getChildrenScale() { //cczheng add don't sclae large hotseat return mIsHotseat ? (LauncherAppState.isDisableAllApps() ? 0.75f : mHotseatScale) : 1.0f; }
4、HotSeat 禁止增删,禁止生成 Folder
禁用长按事件
Launcher3\src\com\android\launcher3\Launcher.java
public boolean onLongClick(View v) {....CellLayout.CellInfo longClickCellInfo = null; View itemUnderLongClick = null; if (v.getTag() instanceof ItemInfo) { ItemInfo info = (ItemInfo) v.getTag(); longClickCellInfo = new CellLayout.CellInfo(v, info); itemUnderLongClick = longClickCellInfo.cell; resetAddInfo(); } //cczheng add , hotseat can't be moved and deleted [S] if (LauncherAppState.isDisableAllApps()) { if(longClickCellInfo != null && longClickCellInfo.container==-101){ return false; } }//E...}
禁止生成 Folder
Launcher3\src\com\android\launcher3\Workspace.java
boolean createUserFolderIfNecessary(View newView, long container, CellLayout target, int[] targetCell, float distance, boolean external, DragView dragView, Runnable postAnimationRunnable) { .... if (v == null || hasntMoved || !mCreateUserFolderOnDrop) { if (LauncherLog.DEBUG) { LauncherLog.d(TAG, "Do not create user folder: hasntMoved = " + hasntMoved + ", mCreateUserFolderOnDrop = " + mCreateUserFolderOnDrop + ", v = " + v); } return false; } //cczheng add don't creat folder in hotseat area [S] if (LauncherAppState.isDisableAllApps() && mLauncher.isHotseatLayout(target)) { Log.e("Launcher3", "isHotseatLayout return false"); return false; } //[E] mCreateUserFolderOnDrop = false; final long screenId = (targetCell == null) ? mDragInfo.screenId : getIdForScreen(target);....}
屏蔽圆形浮窗文件夹背景
Launcher3\src\com\android\launcher3\Workspace.java
public void onDragOver(DragObject d) { if (LauncherLog.DEBUG_DRAG) { LauncherLog.d(TAG, "onDragOver: d = " + d + ", dragInfo = " + d.dragInfo + ", mInScrollArea = " + mInScrollArea + ", mIsSwitchingState = " + mIsSwitchingState); } // Skip drag over events while we are dragging over side pages if (mInScrollArea || !transitionStateShouldAllowDrop()) return; ..... // Handle the drag over if (mDragTargetLayout != null) { // We want the point to be mapped to the dragTarget. if (mLauncher.isHotseatLayout(mDragTargetLayout)) { //cczheng don't show folder cicle when dragtarget in hotseat are if (LauncherAppState.isDisableAllApps()) { Log.d("Launcher3", "don't show folder cicle when dragtarget in hotseat are"); return; }else{//E mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); } } else { mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); }....
5、将 AllAppsContainerView 中的图标加载到 Workspace
Launcher3\src\com\android\launcher3\LauncherModel.java
内部类 LoaderTask 中, run 方法
private class LoaderTask implements Runnable { private Context mContext; @Thunk boolean mIsLoadingAndBindingWorkspace; private boolean mStopped; @Thunk boolean mLoadAndBindStepFinished; private int mFlags; LoaderTask(Context context, int flags) { mContext = context; mFlags = flags; }....public void run() { .... // Optimize for end-user experience: if the Launcher is up and // running with the // All Apps interface in the foreground, load All Apps first. Otherwise, load the // workspace first (default). keep_running: { if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace"); loadAndBindWorkspace(); if (mStopped) { LauncherLog.i(TAG, "LoadTask break in the middle, this = " + this); break keep_running; } waitForIdle(); // second step if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); loadAndBindAllApps(); //cczheng add for load all app shortcut on workspace if (LauncherAppState.isDisableAllApps()) { verifyApplications(); }//E } .... }...
在 loadAndBindAllApps() 附近增加 verifyApplications()
//cczheng add for load all app shortcut on workspaceprivate void verifyApplications() { Log.e("Launcher3", "verifyApplications()"); final Context context = mApp.getContext(); // Cross reference all the applications in our apps list with items in the workspace ArrayList tmpInfos; ArrayList added = new ArrayList(); Log.i("Launcher3", "mBgAllAppsList.data size=="+mBgAllAppsList.data.size()); synchronized (sBgLock) { for (AppInfo app : mBgAllAppsList.data) { tmpInfos = getItemInfoForComponentName(app.componentName, app.user, app.title.toString()); if (tmpInfos.isEmpty()) { // We are missing an application icon, so add this to the workspace added.add(app); // This is a rare event, so lets log it Log.e("Launcher3", "Missing Application on load: " + app); }else{ Log.i("Launcher3", "app.componentName: " + app.componentName); } } } Log.e("Launcher3", "added.isEmpty()="+added.isEmpty()); if (!added.isEmpty()) { addAndBindAddedWorkspaceItems(context, added); }}//Eprivate void loadAndBindAllApps() {....}
内部类 PackageUpdatedTask 中,run 方法
Launcher3\src\com\android\launcher3\LauncherModel.java
private class PackageUpdatedTask implements Runnable { int mOp; String[] mPackages; UserHandleCompat mUser; public static final int OP_NONE = 0; public static final int OP_ADD = 1; public static final int OP_UPDATE = 2; public static final int OP_REMOVE = 3; // uninstlled public static final int OP_UNAVAILABLE = 4; // external media unmounted public PackageUpdatedTask(int op, String[] packages, UserHandleCompat user) { mOp = op; mPackages = packages; mUser = user; } public void run() { .... if (LauncherLog.DEBUG) { LauncherLog.d(TAG, "PackageUpdatedTask: added = " + added + ",modified = " + modified + ",removedApps = " + removedApps); } final HashMap<ComponentName, AppInfo> addedOrUpdatedApps = new HashMap<ComponentName, AppInfo>(); if (added != null) { //cczheng add for load all app shortcut on workspace if (LauncherAppState.isDisableAllApps()) { final ArrayList<ItemInfo> addedInfos = new ArrayList<ItemInfo>(added); addAndBindAddedWorkspaceItems(context, addedInfos); }else{//E addAppsToAllApps(context, added); } for (AppInfo ai : added) { addedOrUpdatedApps.put(ai.componentName, ai); } } ....}
6、去除 Workspace 图标长按删除选项
ButtonDropTarget 的三个实现类,onDragStart() 中 通过 supportsDrop() 控制 ViewGroup 是否显示,那么我只需让 DeleteDropTarget 中 supportsDrop() 为 false
DeleteDropTargetInfoDropTargetUninstallDropTarget
public static boolean supportsDrop(Object info) { //cczheng add for don't show delete icon for shortcut [S] android.util.Log.e("ccz","dele drop "); if (LauncherAppState.isDisableAllApps()) { if (info instanceof ShortcutInfo) { ShortcutInfo item = (ShortcutInfo) info; return item.itemType != LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION; } return info instanceof LauncherAppWidgetInfo; } //cczheng add for don't show delete icon for shortcut [E] return (info instanceof ShortcutInfo) || (info instanceof LauncherAppWidgetInfo) || (info instanceof FolderInfo); }
7、根据全局控制开关,加载不同的布局
Launcher3\src\com\android\launcher3\InvariantDeviceProfile.java
public class InvariantDeviceProfile {....DeviceProfile landscapeProfile; DeviceProfile portraitProfile;//cczheng add boolean isDisableAllApps = LauncherAppState.isDisableAllApps(); InvariantDeviceProfile() { }...ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() { ArrayList<InvariantDeviceProfile> predefinedDeviceProfiles = new ArrayList<>(); .... predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus S", 296, 491.33f, 4, 4, 4, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4)); predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4", 335, 567, 4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4)); predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5", 359, 567, 4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4)); //cczheng add,4x5 xml,5 rows,4 columns [S] predefinedDeviceProfiles.add(new InvariantDeviceProfile("MTK", 375, 567, 5, 4, 5, 4, 4, 56, 10, isDisableAllApps ? 3 : 5, 56, isDisableAllApps ? R.xml.default_workspace_4x5_no_all_apps : R.xml.default_workspace_4x5)); //cczheng add,4x5 xml,5 rows,4 columns [E] predefinedDeviceProfiles.add(new InvariantDeviceProfile("Large Phone", 406, 694, 5, 5, 4, 4, 4, 64, 14.4f, 5, 56, R.xml.default_workspace_5x5)); .... return predefinedDeviceProfiles; }....}
更多相关文章
- Android(安卓)通过Intent简单实现分享功能
- Android应用程序的打包,安装,启动
- CSS3实现android(安卓)Logo图标效果
- Android隐藏导航栏并且禁止其滑出
- Android(安卓)Google Map实例 - 不同的图标标注在同一图层(Andro
- Android(安卓)launcher3布局和结构
- Android5.1 SystemUI 启动流程
- Android之常见图标尺寸
- Android(安卓)2.0环境下的图标设计原则