【Launcher3系列】Android 11 长按图标操作卸载,去掉顶部卸载、移除

您所在的位置:网站首页 小米查询激活日期查询香港 【Launcher3系列】Android 11 长按图标操作卸载,去掉顶部卸载、移除

【Launcher3系列】Android 11 长按图标操作卸载,去掉顶部卸载、移除

2024-05-28 19:09| 来源: 网络整理| 查看: 265

概述

Android系统的Launcher改造在国内算是一个不算很低频的需求,尤其是相当多的三方硬件设备以及部分手机厂商的个性化ROM等,受限于国内整体的开源环境,网上能找到相关的开发资源并不多,最近公司有相关业务需求的开发,就自己涉及到的改造点作一些分享。

原生Launcher自带的长按图标快捷操作区是“应用信息”、“微件”以及其它一些个性化支持操作,而通常需求方出于方便操作及简化用户理解的考虑,希望改造补充“卸载”,且大多同时希望去掉拖动图标时显示在顶部的“卸载、移除”,涉及到的改动点如下:

在长按快捷区增加”卸载“

移除拖动icon时顶部的卸载布局及边界框

不显示顶部的“卸载、移除”

2. 涉及到的类及接口等

在长按快捷区增加”卸载“

com.android.launcher3.Launcher com.android.launcher3.popup.SystemShortcut com.android.launcher3.popup.PopupContainerWithArrow string.xml

移除拖动icon时顶部的卸载布局及边界框

com.android.launcher3.Workspace

不显示顶部的“卸载、移除”

com.android.launcher3.Launcher 3. Show the code

在长按快捷区增加”卸载“

参考APP_INFO内部对象,创建UNINSTALL对象,并添加相应的卸载处理,参考SecondaryDropTarget的performDropAction方法改写。并在string.xml中添加

卸载

SystemShortcut.java

public static final Factory APP_INFO = AppInfo::new; public static class AppInfo extends SystemShortcut { // ... // } //====修改start==== 创建UNINSTALL内部对象 public static final Factory UNINSTALL = UnInstall::new; public static class UnInstall extends SystemShortcut { public UnInstall(BaseDraggingActivity target, ItemInfo itemInfo) { super(R.drawable.ic_uninstall_no_shadow, R.string.app_info_drop_uninstall_label, target, itemInfo); } @Override public void onClick(View view) { dismissTaskMenuView(mTarget); ComponentName cn = getUninstallTarget(mItemInfo); if (cn == null) { // System applications cannot be installed. For now, show a toast explaining that. // We may give them the option of disabling apps this way. Toast.makeText(mTarget, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show(); return; } try { Intent i = Intent.parseUri(mTarget.getString(R.string.delete_package_intent), 0) .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName())) .putExtra(Intent.EXTRA_USER, mItemInfo.user); mTarget.startActivity(i); FileLog.d("Uninstall", "start uninstall activity " + cn.getPackageName()); return; } catch (URISyntaxException e) { Log.e("Uninstall", "Failed to parse intent to start uninstall activity for item=" + mItemInfo); return; } } } /** * @return the component name that should be uninstalled or null. */ ComponentName getUninstallTarget(ItemInfo item) { Intent intent = null; UserHandle user = null; if (item != null && item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { intent = item.getIntent(); user = item.user; } if (intent != null) { LauncherActivityInfo info = mTarget.getSystemService(LauncherApps.class) .resolveActivity(intent, user); if (info != null && (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) { return info.getComponentName(); } } return null; } //====修改end==== public static final Factory INSTALL = (activity, itemInfo) -> { // ... // };

Launcher.java

public Stream getSupportedShortcuts() { //====修改==== 添加UNINSTALL return Stream.of(APP_INFO, WIDGETS,INSTALL,UNINSTALL); }

PopupContainerWithArrow.java

public class PopupContainerWithArrow extends ArrowPopup implements DragSource, DragController.DragListener { // ... // @TargetApi(Build.VERSION_CODES.P) public void populateAndShow(final BubbleTextView originalIcon, int shortcutCount, final List notificationKeys, List systemShortcuts) { mNumNotifications = notificationKeys.size(); mOriginalIcon = originalIcon; //====修改==== 将hasDeepShortcuts置为false,以屏蔽部分APP额外支持的快捷操 boolean hasDeepShortcuts = false;//shortcutCount > 0; int containerWidth = (int) getResources().getDimension(R.dimen.bg_popup_item_width); // if there are deep shortcuts, we might want to increase the width of shortcuts to fit // horizontally laid out system shortcuts. //hasDeepShortcuts表示该图标是否还有快捷操作,比如时钟APP还有快捷的"启动屏保、启支秒表"等 if (hasDeepShortcuts) { containerWidth = (int) Math.max(containerWidth, systemShortcuts.size() * getResources().getDimension( R.dimen.system_shortcut_header_icon_touch_size)); } // Add views if (mNumNotifications > 0) { // Add notification entries View.inflate(getContext(), R.layout.notification_content, this); mNotificationItemView = new NotificationItemView(this); if (mNumNotifications == 1) { mNotificationItemView.removeFooter(); } else { mNotificationItemView.setFooterWidth(containerWidth); } updateNotificationHeader(); } int viewsToFlip = getChildCount(); mSystemShortcutContainer = this; //有快捷操作才进,咱不进 if (hasDeepShortcuts) { if (mNotificationItemView != null) { mNotificationItemView.addGutter(); } for (int i = shortcutCount; i > 0; i--) { DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, this); v.getLayoutParams().width = containerWidth; mShortcuts.add(v); } updateHiddenShortcuts(); if (!systemShortcuts.isEmpty()) { mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons, this); for (SystemShortcut shortcut : systemShortcuts) { initializeSystemShortcut( R.layout.system_shortcut_icon_only, mSystemShortcutContainer, shortcut); } } } else if (!systemShortcuts.isEmpty()) { if (mNotificationItemView != null) { mNotificationItemView.addGutter(); } for (SystemShortcut shortcut : systemShortcuts) { //这里是长按图标后弹出的操作项item样式 //====修改start==== 添加快捷操作过滤,如果想保留“应用信息”,可同理处理 if(shortcut instanceof SystemShortcut.UnInstall){ initializeSystemShortcut(R.layout.system_shortcut, this, shortcut); } //====修改end==== } } reorderAndShow(viewsToFlip); ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag(); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { setAccessibilityPaneTitle(getTitleForAccessibility()); } mOriginalIcon.setForceHideDot(true); // All views are added. Animate layout from now on. setLayoutTransition(new LayoutTransition()); // Load the shortcuts on a background thread and update the container as it animates. MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable( mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()), this, mShortcuts, notificationKeys)); } // ... // /** * Utility class to handle updates while the popup is visible (like widgets and * notification changes) */ private class LiveUpdateHandler implements PopupDataChangeListener, View.OnAttachStateChangeListener { private final Launcher mLauncher; LiveUpdateHandler(Launcher launcher) { mLauncher = launcher; } @Override public void onViewAttachedToWindow(View view) { mLauncher.getPopupDataProvider().setChangeListener(this); } @Override public void onViewDetachedFromWindow(View view) { mLauncher.getPopupDataProvider().setChangeListener(null); } @Override public void onWidgetsBound() { ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag(); SystemShortcut widgetInfo = SystemShortcut.WIDGETS.getShortcut(mLauncher, itemInfo); View widgetsView = null; int count = mSystemShortcutContainer.getChildCount(); for (int i = 0; i widgetsView = systemShortcutView; break; } } if (widgetInfo != null && widgetsView == null) { // We didn't have any widgets cached but now there are some, so enable the shortcut. if (mSystemShortcutContainer != PopupContainerWithArrow.this) { initializeSystemShortcut(R.layout.system_shortcut_icon_only, mSystemShortcutContainer, widgetInfo); } //else { //====修改start==== 将else处理注释掉,否则在某些系统APP长按时会有循环闪烁动画 // If using the expanded system shortcut (as opposed to just the icon), we need // to reopen the container to ensure measurements etc. all work out. While this // could be quite janky, in practice the user would typically see a small // flicker as the animation restarts partway through, and this is a very rare // edge case anyway. // close(false); // PopupContainerWithArrow.showForIcon(mOriginalIcon); // } //====修改end==== } else if (widgetInfo == null && widgetsView != null) { // No widgets exist, but we previously added the shortcut so remove it. if (mSystemShortcutContainer != PopupContainerWithArrow.this) { mSystemShortcutContainer.removeView(widgetsView); } else { close(false); PopupContainerWithArrow.showForIcon(mOriginalIcon); } } } // ... // }

移除拖动icon时顶部的卸载布局及边界框

Workspace.java

@Override public void onDragStart(DragObject dragObject, DragOptions options) { // ... // if (addNewPage) { mDeferRemoveExtraEmptyScreen = false; addExtraEmptyScreenOnDrag(); if (dragObject.dragInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET && dragObject.dragSource != this) { // When dragging a widget from different source, move to a page which has // enough space to place this widget (after rearranging/resizing). We special case // widgets as they cannot be placed inside a folder. // Start at the current page and search right (on LTR) until finding a page with // enough space. Since an empty screen is the furthest right, a page must be found. int currentPage = getPageNearestToCenterOfScreen(); for (int pageIndex = currentPage; pageIndex setCurrentPage(pageIndex); break; } } } } // Always enter the spring loaded mode //====修改==== 注释掉这一行即可移除长按出现的卸载布局及边界框 // mLauncher.getStateManager().goToState(SPRING_LOADED); mStatsLogManager.logger().withItemInfo(dragObject.dragInfo) .withInstanceId(dragObject.logInstanceId) .log(LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED); }

不显示顶部的“卸载、移除”

Launcher.java

protected void setupViews() { mDragLayer = findViewById(R.id.drag_layer); mFocusHandler = mDragLayer.getFocusIndicatorHelper(); mWorkspace = mDragLayer.findViewById(R.id.workspace); mWorkspace.initParentViews(mDragLayer); mOverviewPanel = findViewById(R.id.overview_panel); mHotseat = findViewById(R.id.hotseat); mHotseat.setWorkspace(mWorkspace); // Setup the drag layer mDragLayer.setup(mDragController, mWorkspace); mWorkspace.setup(mDragController); // Until the workspace is bound, ensure that we keep the wallpaper offset locked to the // default state, otherwise we will update to the wrong offsets in RTL mWorkspace.lockWallpaperToDefaultPage(); mWorkspace.bindAndInitFirstWorkspaceScreen(null /* recycled qsb */); mDragController.addDragListener(mWorkspace); // Get the search/delete/uninstall bar mDropTargetBar = mDragLayer.findViewById(R.id.drop_target_bar); // Setup Apps mAppsView = findViewById(R.id.apps_view); // Setup Scrim mScrimView = findViewById(R.id.scrim_view); // Setup the drag controller (drop targets have to be added in reverse order in priority) //====修改==== 这里注释掉顶部卸载栏的初始化及监听,则长按不会显示卸载、移除按钮 // mDropTargetBar.setup(mDragController); mAllAppsController.setupViews(mAppsView, mScrimView); } 4. 结语

以上为将系统初始的双层屏改为单层涉及到的全部改动,供参考。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3