效果图
修改思路
1、增加变量 launcher3.is_full_app,用来动态切换
2、增加两套布局,对应有抽屉和无抽屉
3、去除 allAppsButton
4、将 AllAppsContainerView 中的图标加载到 Workspace
5、新安装的 app 自动添加图标到 Workspace
6、替换 Workspace 图标长按删除选项为取消
7、屏蔽上拉显示抽屉页面手势
8、修改页面指示线为圆点
modified: packages/apps/Launcher3/Android.mk
modified: packages/apps/Launcher3/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
modified: packages/apps/Launcher3/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
modified: packages/apps/Launcher3/res/layout/launcher.xml
modified: packages/apps/Launcher3/res/values/dimens.xml
modified: packages/apps/Launcher3/res/xml/device_profiles.xml
modified: packages/apps/Launcher3/src/com/android/launcher3/DeleteDropTarget.java
modified: packages/apps/Launcher3/src/com/android/launcher3/Hotseat.java
modified: packages/apps/Launcher3/src/com/android/launcher3/InvariantDeviceProfile.java
modified: packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
modified: packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java
modified: packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
modified: packages/apps/Launcher3/src/com/android/launcher3/dragndrop/DragController.java
modified: packages/apps/Launcher3/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
modified: packages/apps/Launcher3/src/com/android/launcher3/model/BaseModelUpdateTask.java
modified: packages/apps/Launcher3/src/com/android/launcher3/model/ItemInstallQueue.java
modified: packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java
modified: packages/apps/Launcher3/src/com/android/launcher3/model/PackageUpdatedTask.java
modified: packages/apps/Launcher3/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
modified: packages/apps/Launcher3/src/com/android/launcher3/settings/SettingsActivity.java
上代码
1、在 LauncherAppState 中增加静态方法 isDisableAllApps()
packages\apps\Launcher3\src\com\android\launcher3\LauncherAppState.java
public static boolean isDisableAllApps() {
return true;
}
2、增加两套布局,对应有抽屉和无抽屉
加载布局文件对应的 xml 为 packages\apps\Launcher3\res\xml\device_profiles.xml
Launcher3 通过获取 minWidthDps 和 minHeightDps 来确定加载哪一个 profile,增加两个 profile 节点
+ <!-- cczheng add -->
+ <grid-option
+ launcher:name="4_by_4"
+ launcher:numRows="4"
+ launcher:numColumns="4"
+ launcher:numFolderRows="3"
+ launcher:numFolderColumns="4"
+ launcher:numHotseatIcons="4"
+ launcher:dbFile="launcher_4_by_4.db"
+ launcher:defaultLayoutId="@xml/default_workspace_4x4_no_all_app" >
+
+ <display-option
+ launcher:name="Short Stubby"
+ launcher:minWidthDps="260"
+ launcher:minHeightDps="410"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="13.0"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Stubby"
+ launcher:minWidthDps="255"
+ launcher:minHeightDps="450"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="13.0"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Nexus S"
+ launcher:minWidthDps="296"
+ launcher:minHeightDps="491.33"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="13.0"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Nexus 4"
+ launcher:minWidthDps="359"
+ launcher:minHeightDps="567"
+ launcher:iconImageSize="54"
+ launcher:iconTextSize="13.0"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Nexus 5"
+ launcher:minWidthDps="335"
+ launcher:minHeightDps="567"
+ launcher:iconImageSize="54"
+ launcher:iconTextSize="13.0"
+ launcher:canBeDefault="true" />
+ </grid-option>
+ <!-- end -->
+
对应的你需要在 xml 文件下增加 1 个文件, default_workspace_4x4_no_all_app.xml
这样的好处是你可以自定义不同的布局文件加载内容,上面的配置含义简单说一下,分别是最小宽度、最小高度、布局的行和列、文件夹中布局行和列、图标大小、图标文字大小、HotSeat 个数,加载的布局文件
在 InvariantDeviceProfile() 判断是否需要加载 Tablet_no_all_app profile
packages\apps\Launcher3\src\com\android\launcher3\InvariantDeviceProfile.java
+import android.util.Log;
+
public class InvariantDeviceProfile {
public static final String TAG = "IDP";
@@ -494,26 +496,40 @@ public class InvariantDeviceProfile {
}
}
+ Log.d("Launcher3.profiles", "minWidthPx="+minWidthPx + " minHeightPx="+minHeightPx);
float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
+ Log.i("Launcher3.profiles", "width="+width + " height="+height);
+
+ if (LauncherAppState.isDisableAllApps()) {
+ Log.e("Launcher3.profiles", "load no all app profiles");
+
+ width = 260.0f;
+ height = 410.0f;
+ }
+ final float widthFix = width;
+ final float heightFix = height;
+
Collections.sort(points, (a, b) ->
- Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps),
- dist(width, height, b.minWidthDps, b.minHeightDps)));
+ Float.compare(dist(widthFix, heightFix, a.minWidthDps, a.minHeightDps),
+ dist(widthFix, heightFix, b.minWidthDps, b.minHeightDps)));
GridOption closestOption = points.get(0).grid;
float weights = 0;
DisplayOption p = points.get(0);
- if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
+
+ if (dist(widthFix, heightFix, p.minWidthDps, p.minHeightDps) == 0) {
return p;
}
DisplayOption out = new DisplayOption(closestOption);
for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
p = points.get(i);
- float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
+
+ float w = weight(widthFix, heightFix, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
weights += w;
out.add(new DisplayOption().add(p).multiply(w));
}
3、去除 allAppsButton
packages\apps\Launcher3\src\com\android\launcher3\Hotseat.java
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+import static com.android.launcher3.LauncherState.ALL_APPS;
+
+
+
+
@@ -50,7 +59,9 @@ public class Hotseat extends CellLayout implements Insettable {
private final int mQsbHeight;
private final int mTaskbarViewHeight;
-
+
+ private final Launcher mLauncher;
+
public Hotseat(Context context) {
this(context, null);
}
@@ -67,7 +78,9 @@ public class Hotseat extends CellLayout implements Insettable {
addView(mQsb);
mTaskbarViewHeight = context.getResources().getDimensionPixelSize(R.dimen.taskbar_size);
- }
+
+ mLauncher = Launcher.getLauncher(context);
+ }
4、将 AllAppsContainerView 中的图标加载到 Workspace
packages\apps\Launcher3\src\com\android\launcher3\model\LoaderTask.java
run() 中增加判断,添加 verifyApplications(), 修改 ItemInstallQueue 中 PendingInstallShortcutInfo 为 public
+import android.util.Pair;
这个很关键,系统 app 就不创建 icon 了,无抽屉下需要放开
packages\apps\Launcher3\src\com\android\launcher3\model\AddWorkspaceItemsTask.java
@@ -82,9 +82,12 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
}
- if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
- continue;
- }
+
+ if (!LauncherAppState.isDisableAllApps()) {
+ if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
+ continue;
+ }
+ }
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
packages\apps\Launcher3\src\com\android\launcher3\model\BaseModelUpdateTask.java
注释 run() 中的 return
@@ -67,7 +67,8 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
Log.d(TAG, "Ignoring model task since loader is pending=" + this);
}
- return;
+
+
}
execute(mApp, mDataModel, mAllAppsList);
}
5、新安装的 app 自动添加图标到 Workspace
packages\apps\Launcher3\src\com\android\launcher3\model\PackageUpdatedTask.java
execute() 中增加判断,添加 updateToWorkSpace()
+import android.content.pm.LauncherActivityInfo;
+import android.util.Pair;
+import com.android.launcher3.model.data.AppInfo;
+
+
@@ -358,7 +363,46 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
}
bindUpdatedWidgets(dataModel);
}
+
+
+ if (LauncherAppState.isDisableAllApps()) {
+ android.util.Log.e("cczLauncher3", "updateToWorkSpace()");
+ updateToWorkSpace(context, app, appsList);
+ }
+
+ }
+
+
+ public void updateToWorkSpace(Context context, LauncherAppState app , AllAppsList appsList){
+ ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
+
+ UserManager mUserManager = context.getSystemService(UserManager.class);
+ LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
+ final List<UserHandle> profiles = mUserManager.getUserProfiles();
+ ArrayList<ItemInstallQueue.PendingInstallShortcutInfo> added
+ = new ArrayList<ItemInstallQueue.PendingInstallShortcutInfo>();
+
+ for (UserHandle user : profiles) {
+
+ final List<LauncherActivityInfo> apps = launcherApps.getActivityList(null, user);
+ synchronized (this) {
+ for (LauncherActivityInfo info : apps) {
+ for (AppInfo appInfo : appsList.data) {
+ if(info.getComponentName().equals(appInfo.componentName)){
+ ItemInstallQueue.PendingInstallShortcutInfo mPendingInstallShortcutInfo
+ = new ItemInstallQueue.PendingInstallShortcutInfo(info.getComponentName().getPackageName(), info.getUser());
+ added.add(mPendingInstallShortcutInfo);
+ installQueue.add(mPendingInstallShortcutInfo.getItemInfo(context));
+ }
+ }
+ }
+ }
+ }
+ if (!added.isEmpty()) {
+ app.getModel().addAndBindAddedWorkspaceItems(installQueue);
+ }
}
+
6、替换 Workspace 图标长按删除选项为取消
packages\apps\Launcher3\src\com\android\launcher3\DeleteDropTarget.java
在 setTextBasedOnDragSource() 、setControlTypeBasedOnDragSource()、onAccessibilityDrop() 中分别增加判断是否需要删除图标
@@ -95,6 +95,14 @@ public class DeleteDropTarget extends ButtonDropTarget {
mText = getResources().getString(canRemove(item)
? R.string.remove_drop_target_label
: android.R.string.cancel);
+
+ if (LauncherAppState.isDisableAllApps()) {
+ android.util.Log.e("Launcher3", "hide delete drop target");
+ mText = getResources().getString(isCanDrop(item)
+ ? R.string.remove_drop_target_label
+ : android.R.string.cancel);
+ }
+
setContentDescription(mText);
requestLayout();
}
@@ -110,6 +118,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
private void setControlTypeBasedOnDragSource(ItemInfo item) {
mLauncherEvent = item.id != ItemInfo.NO_ID ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
: LAUNCHER_ITEM_DROPPED_ON_CANCEL;
+
+ if (LauncherAppState.isDisableAllApps()) {
+ mLauncherEvent = isCanDrop(item) ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
+ : LAUNCHER_ITEM_DROPPED_ON_CANCEL;
+ }
}
@Override
@@ -135,8 +148,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
modelWriter.abortDelete();
mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
};
- Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
+
+ if (!LauncherAppState.isDisableAllApps()){
+ Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
modelWriter::commitDelete, onUndoClicked);
+ }
}
}
@@ -148,9 +164,18 @@ public class DeleteDropTarget extends ButtonDropTarget {
- mLauncher.removeItem(view, item, true );
- mLauncher.getWorkspace().stripEmptyScreens();
- mLauncher.getDragLayer()
- .announceForAccessibility(getContext().getString(R.string.item_removed));
+
+ if (!LauncherAppState.isDisableAllApps() || isCanDrop(item)) {
+ mLauncher.removeItem(view, item, true );
+ mLauncher.getWorkspace().stripEmptyScreens();
+ mLauncher.getDragLayer()
+ .announceForAccessibility(getContext().getString(R.string.item_removed));
+ }
+ }
+
+
+ private boolean isCanDrop(ItemInfo item){
+ return !(item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
}
}
packages\apps\Launcher3\src\com\android\launcher3\dragndrop\DragController.java
drop() 中增加判断,取消当前拖拽操作
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.DeleteDropTarget;
+
@@ -525,12 +529,25 @@ public abstract class DragController<T extends ActivityContext>
dropTarget.onDrop(mDragObject, mOptions);
}
accepted = true;
+
+
+ if (LauncherAppState.isDisableAllApps() && dropTarget instanceof DeleteDropTarget &&
+ isNeedCancelDrag(mDragObject.dragInfo)) {
+ cancelDrag();
+ }
+
}
}
final View dropTargetAsView = dropTarget instanceof View ? (View) dropTarget : null;
dispatchDropComplete(dropTargetAsView, accepted);
}
+
+ private boolean isNeedCancelDrag(ItemInfo item){
+ return (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
+ }
+
private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
mDragObject.x = x;
mDragObject.y = y;
7、屏蔽上拉显示抽屉页面手势
packages\apps\Launcher3\quickstep\src\com\android\launcher3\uioverrides\touchcontrollers\PortraitStatesTouchController.java
canInterceptTouch() 中增加判断是否直接拦截
+import com.android.launcher3.LauncherAppState;
+
@@ -78,6 +80,12 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
+
+ if (LauncherAppState.isDisableAllApps()){
+ android.util.Log.e("Launcher3", "canInterceptTouch()");
+ return false;
+ }
+
boolean interceptAnywhere = mLauncher.isInState(NORMAL);
if (mCurrentAnimation != null) {
8、修改页面指示线为圆点
packages\apps\Launcher3\res\layout\launcher.xml
WorkspacePageIndicator 改为 PageIndicatorDots
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
- <com.android.launcher3.pageindicators.WorkspacePageIndicator
+ <!-- cczheng change WorkspacePageIndicator line to dot @dimen/workspace_page_indicator_height-->
+ <!-- <com.android.launcher3.pageindicators.WorkspacePageIndicator -->
+ <com.android.launcher3.pageindicators.PageIndicatorDots
android:id="@+id/page_indicator"
android:layout_width="match_parent"
- android:layout_height="@dimen/workspace_page_indicator_height"
+ android:layout_height="4dp"
android:layout_gravity="bottom|center_horizontal"
android:theme="@style/HomeScreenElementTheme" />
packages\apps\Launcher3\src\com\android\launcher3\Workspace.java
+import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -129,7 +130,8 @@ import java.util.stream.Collectors;
* Each page contains a number of icons, folders or widgets the user can
* interact with. A workspace is meant to be used with a fixed width only.
*/
-public class Workspace extends PagedView<WorkspacePageIndicator>
+
+public class Workspace extends PagedView<PageIndicatorDots>
implements DropTarget, DragSource, View.OnTouchListener,
DragController.DragListener, Insettable, StateHandler<LauncherState>,
WorkspaceLayoutManager {
packages\apps\Launcher3\src\com\android\launcher3\pageindicators\PageIndicatorDots.java
增加 PageIndicatorDots 继承 Insettable,复写setInsets(), 调整圆点的位置
import com.android.launcher3.util.Themes;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import android.widget.FrameLayout;
+import android.graphics.Rect;
+import android.view.Gravity;
-public class PageIndicatorDots extends View implements PageIndicator {
+public class PageIndicatorDots extends View implements PageIndicator, Insettable {
private static final float SHIFT_PER_ANIMATION = 0.5f;
private static final float SHIFT_THRESHOLD = 0.1f;
@@ -97,6 +103,7 @@ public class PageIndicatorDots extends View implements PageIndicator {
private float[] mEntryAnimationRadiusFactors;
+ private final Launcher mLauncher;
public PageIndicatorDots(Context context) {
this(context, null);
}
@@ -117,8 +124,27 @@ public class PageIndicatorDots extends View implements PageIndicator {
mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
mIsRtl = Utilities.isRtl(getResources());
+ mLauncher = Launcher.getLauncher(context);
}
+
+ @Override
+ public void setInsets(Rect insets) {
+ DeviceProfile grid = mLauncher.getDeviceProfile();
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
+
+ if (grid.isVerticalBarLayout()) {
+ Rect padding = grid.workspacePadding;
+ lp.leftMargin = padding.left + grid.workspaceCellPaddingXPx;
+ lp.rightMargin = padding.right + grid.workspaceCellPaddingXPx;
+ lp.bottomMargin = padding.bottom;
+ } else {
+ lp.leftMargin = lp.rightMargin = 0;
+ lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ lp.bottomMargin = grid.hotseatBarSizePx + insets.bottom;
+ }
+ setLayoutParams(lp);
+ }
@Override
public void setScroll(int currentScroll, int totalScroll) {
if (mNumPages > 1) {
@@ -126,6 +152,10 @@ public class PageIndicatorDots extends View implements PageIndicator {
currentScroll = totalScroll - currentScroll;
}
int scrollPerPage = totalScroll / (mNumPages - 1);
+
+ if (scrollPerPage == 0) {
+ return;
+ }
int pageToLeft = currentScroll / scrollPerPage;
int pageToLeftScroll = pageToLeft * scrollPerPage;
int pageToRightScroll = pageToLeftScroll + scrollPerPage;
packages\apps\Launcher3\src\com\android\launcher3\Launcher.java
protected int mPendingActivityRequestCode = -1;
- private ViewGroupFocusHelper mFocusHandler;
+ public ViewGroupFocusHelper mFocusHandler;
private RotationHelper mRotationHelper;
@@ -1038,8 +1038,8 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
mWorkspace.showPageIndicatorAtCurrentScroll();
mWorkspace.setClipChildren(false);
}
-
- mWorkspace.getPageIndicator().setShouldAutoHide(!state.hasFlag(FLAG_MULTI_PAGE));
+
+
mPrevLauncherState = mStateManager.getCurrentStableState();
if (mPrevLauncherState != state && ALL_APPS.equals(state)
packages\apps\Launcher3\quickstep\src\com\android\launcher3\QuickstepTransitionManager.java
}
- mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+
endListener = () -> {
viewsToAnimate.forEach(view -> {
@@ -540,7 +540,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
if (scrimEnabled) {
mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
}
- mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+
};
}
|