前言
按照惯例 Launcher3 源码存在两份,分别位于 package/app/和vendor/mediatek/proprietary/packages/apps/下,vendor下的mk中使用 LOCAL_OVERRIDES_PACKAGES 属性覆盖 package 下的源码,所以我们要改的源码就是 vendor 下的。但是在 Q 中并不是这样的,编译后的Launcher3 app 路径为 product/priv-app/MtkLauncher3QuickStep/,来看下 mk,可以看到编译 MtkLauncher3QuickStep 并没有引用当前目录下的源码文件,并没有 LOCAL_SRC_FILES := \,而是引入静态库 Launcher3QuickStepLib
LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3QuickStepLib
vendor\mediatek\proprietary\packages\apps\Launcher3\Android.mk
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # # Build rule for Quickstep app. # include $(CLEAR_VARS) LOCAL_USE_AAPT2 := true LOCAL_MODULE_TAGS := optional .... LOCAL_PACKAGE_NAME := MtkLauncher3QuickStep LOCAL_PRIVILEGED_MODULE := true LOCAL_PRODUCT_MODULE := true LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3 Launcher3QuickStep LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3 LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/quickstep/res \ $(LOCAL_PATH)/quickstep/recents_ui_overrides/res LOCAL_FULL_LIBS_MANIFEST_FILES := \ $(LOCAL_PATH)/AndroidManifest.xml \ $(LOCAL_PATH)/AndroidManifest-common.xml LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.* include $(BUILD_PACKAGE) |
静态库编译在 packages\apps\Launcher3\Android.mk,所以不管你怎么修改 vendor下 Launcher3 的源码,编译都不生效,要去修改
packages\apps\Launcher3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # # Build rule for Quickstep library. # include $(CLEAR_VARS) ..... LOCAL_MODULE := Launcher3QuickStepLib LOCAL_PRIVILEGED_MODULE := true LOCAL_STATIC_ANDROID_LIBRARIES := \ Launcher3CommonDepsLib \ SecondaryDisplayLauncherLib LOCAL_SRC_FILES := \ $(call all-java-files-under, src) \ $(call all-java-files-under, quickstep/src) \ $(call all-java-files-under, quickstep/recents_ui_overrides/src) \ $(call all-java-files-under, src_flags) \ $(call all-java-files-under, src_shortcuts_overrides) LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/quickstep/res \ $(LOCAL_PATH)/quickstep/recents_ui_overrides/res LOCAL_PROGUARD_ENABLED := disabled LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml include $(BUILD_STATIC_JAVA_LIBRARY) |
为了方便调试修改我们编译 userdebug 版本,可直接 push 替换效果。为了避免每次改动后整编烧写的麻烦,我还是直接修改 vendor中的Launcher3,新建一个android.mk,单独编译时引入当前路径下的源码,效果确认后再拷贝至 package 中 Launcher3 即可,每次修改源码后 mmm 得到 apk,push 进去,kill 进程查看效果。
vendor\mediatek\proprietary\packages\apps\Launcher3\Android.mk
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | LOCAL_PATH := $(call my-dir) # # Build rule for Quickstep app. # include $(CLEAR_VARS) LOCAL_USE_AAPT2 := true LOCAL_MODULE_TAGS := optional LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3QuickStepLib LOCAL_PROGUARD_ENABLED := disabled ifneq (,$(wildcard frameworks/base)) LOCAL_PRIVATE_PLATFORM_APIS := true else LOCAL_SDK_VERSION := system_current LOCAL_MIN_SDK_VERSION := 26 endif LOCAL_PACKAGE_NAME := MtkLauncher3QuickStep LOCAL_PRIVILEGED_MODULE := true LOCAL_PRODUCT_MODULE := true LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3 Launcher3QuickStep LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3 LOCAL_SRC_FILES := \ $(call all-java-files-under, src) \ $(call all-java-files-under, quickstep/src) LOCAL_RESOURCE_DIR := \ $(LOCAL_PATH)/quickstep/res \ $(LOCAL_PATH)/quickstep/recents_ui_overrides/res LOCAL_FULL_LIBS_MANIFEST_FILES := \ $(LOCAL_PATH)/AndroidManifest.xml \ $(LOCAL_PATH)/AndroidManifest-common.xml LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.* include $(BUILD_PACKAGE) # ================================================== include $(call all-makefiles-under,$(LOCAL_PATH)) |
一、去掉默认 Google 搜索栏
修改位置
packages\apps\Launcher3\src\com\android\launcher3\Workspace.java
注释 bindAndInitFirstWorkspaceScreen() 中 if (qsb == null) 开始到结尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public void bindAndInitFirstWorkspaceScreen(View qsb) { if (!FeatureFlags.QSB_ON_FIRST_SCREEN) { return; } // Add the first page CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, 0); if (FeatureFlags.PULLDOWN_SEARCH) { ..... } //add don't show google quick search box[qsb] // Always add a QSB on the first screen. /*if (qsb == null) { // In transposed layout, we add the QSB in the Grid. As workspace does not touch the // edges, we do not need a full width QSB. qsb = LayoutInflater.from(getContext()) .inflate(R.layout.search_container_workspace,firstPage, false); } CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1); lp.canReorder = false; if (!firstPage.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true)) { Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout"); }*/ //add don't show google quick search box[qsb] } |
二、去掉所有 app 界面搜索应用栏
修改位置
packages\apps\Launcher3\src\com\android\launcher3\allapps\AllAppsContainerView.java
在 onFinishInflate() 中添加一行 mSearchContainer.setVisibility(View.GONE);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Override protected void onFinishInflate() { super.onFinishInflate(); .... mSearchContainer = findViewById(R.id.search_container_all_apps); mSearchUiManager = (SearchUiManager) mSearchContainer; mSearchUiManager.initialize(mApps, mAppsRecyclerView); /// add this code don't show all app quick search box mSearchContainer.setVisibility(View.GONE); ...... } |
packages\apps\Launcher3\src\com\android\launcher3\allapps\AllAppsTransitionController.java
注释setAlphas() 中的 mAppsView.getSearchUiManager()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public void setAlphas(int visibleElements, AnimationConfig config, AnimatorSetBuilder builder) { PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER : config.getPropertySetter(builder); boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0; boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0; Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR); setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade); setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade); mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter, allAppsFade); ///annotaion this code don't show all app quick search box //mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade); setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA, (visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, allAppsFade); } |
三、hotseat 位置居于底部
之前版本 lp.gravity 都在 DeviceProfile 中修改,Q 中移到了 Hotseat 类里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | @Override public void setInsets(Rect insets) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); DeviceProfile grid = mActivity.getWallpaperDeviceProfile(); insets = grid.getInsets(); if (grid.isVerticalBarLayout()) { lp.height = ViewGroup.LayoutParams.MATCH_PARENT; if (grid.isSeascape()) { lp.gravity = Gravity.LEFT; lp.width = grid.hotseatBarSizePx + insets.left; } else { lp.gravity = Gravity.RIGHT; lp.width = grid.hotseatBarSizePx + insets.right; } } else { lp.gravity = Gravity.BOTTOM; lp.width = ViewGroup.LayoutParams.MATCH_PARENT; lp.height = grid.hotseatBarSizePx + insets.bottom; } Rect padding = grid.getHotseatLayoutPadding(); setPadding(padding.left, padding.top, padding.right, padding.bottom); setLayoutParams(lp); InsettableFrameLayout.dispatchInsets(this, insets); } |
为了不影响其它间距计算我们去修改 grid.isVerticalBarLayout()
packages\apps\Launcher3\src\com\android\launcher3\DeviceProfile.java
将 transposeLayoutWithOrientation 置为 false 即可
1 2 3 4 5 6 7 | // Some more constants transposeLayoutWithOrientation = false; //res.getBoolean(R.bool.hotseat_transpose_layout_with_orientation); public boolean isVerticalBarLayout() { return isLandscape && transposeLayoutWithOrientation; } |
四、workspace 图标不显示文字bug修改
经过 log 打印发现 display == DISPLAY_WORKSPACE 时,textsize 和 padding 均为 0,所以文字不显示,直接注释当前 if,和
display == DISPLAY_ALL_APPS 共用逻辑
packages/apps/Launcher3/src/com/android/launcher3/BubbleTextView.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public BubbleTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mActivity = ActivityContext.lookupContext(context); mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BubbleTextView, defStyle, 0); mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false); int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE); final int defaultIconSize; //annotaion code because textsize and padding is 0 don't show text /* if (display == DISPLAY_WORKSPACE) { android.util.Log.i("Launcher3","WorkspaceItemInfo"); DeviceProfile grid = mActivity.getWallpaperDeviceProfile(); setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);//0 setCompoundDrawablePadding(grid.iconDrawablePaddingPx);//0 defaultIconSize = grid.iconSizePx; android.util.Log.i("Launcher3","DISPLAY_WORKSPACE iconTextSizePx="+grid.iconTextSizePx); android.util.Log.i("Launcher3","DISPLAY_WORKSPACE iconDrawablePaddingPx="+grid.iconDrawablePaddingPx); } else */if (display == DISPLAY_WORKSPACE || display == DISPLAY_ALL_APPS) { DeviceProfile grid = mActivity.getDeviceProfile(); setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx); defaultIconSize = grid.allAppsIconSizePx; android.util.Log.d("Launcher3","DISPLAY_ALL_APPS allAppsIconTextSizePx="+grid.allAppsIconTextSizePx); android.util.Log.d("Launcher3","DISPLAY_ALL_APPS allAppsIconDrawablePaddingPx="+grid.allAppsIconDrawablePaddingPx); } |
五、icon 图标去除多余白边
packages/apps/Launcher3/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) { float scale = 1f; android.util.Log.e("Launcher3","normalizeAndWrapToAdaptiveIcon..."); //annotation for don't add white mask outshape when targetsdk >= 26 /*if (shrinkNonAdaptiveIcons && ATLEAST_OREO) { if (mWrapperIcon == null) { mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper) .mutate(); } AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon; dr.setBounds(0, 0, 1, 1); boolean[] outShape = new boolean[1]; scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape); if (!(icon instanceof AdaptiveIconDrawable) && !outShape[0]) { FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground()); fsd.setDrawable(icon); fsd.setScale(scale); icon = dr; scale = getNormalizer().getScale(icon, outIconBounds, null, null); ((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor); } } else { scale = getNormalizer().getScale(icon, outIconBounds, null, null); }*/ scale = getNormalizer().getScale(icon, outIconBounds, null, null); outScale[0] = scale; return icon; } |