Android Launcher3修改长按屏幕空白处进入OverviewMode模式,进入OverviewMode模式点击Home无法复原的bug

本文介绍如何通过修改Launcher类中的onLongClick方法来控制用户长按空白处不进入OverviewMode模式,并解决了长按后无法退出的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果想控制用户长按空白处,不进入OverviewMode模式,只需修改Laucnher类中的onLongClick方法。

长按workspace的空白处进入OverviewMode模式,如果不想进入,注释掉enterOverviewMode这行代码

 if(v instanceof Workspace){
        if (!mWorkspace.isInOverviewMode()) {
            if (mWorkspace.enterOverviewMode()) {
                mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

同样,长按Hostseat空白处,也要控制是否进入OverviewMode模式,处理同上。

// The hotseat touch handling does not go through Workspace, and we always allow long press
// on hotseat items.
final boolean inHotseat = isHotseatLayout(v);
boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();
if (allowLongPress && !mDragController.isDragging()) {
    if (itemUnderLongClick == null) {
        // User long pressed on empty space
        mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
        if (mWorkspace.isInOverviewMode()) {
            mWorkspace.startReordering(v);
        } else {
            mWorkspace.enterOverviewMode();
        }
    } else {
        final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(
                mHotseat.getOrderInHotseat(
                        longClickCellInfo.cellX,
                        longClickCellInfo.cellY));
        if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {
            // User long pressed on an item
            mWorkspace.startDrag(longClickCellInfo);
        }
    }
}

进入OverviewMode模式,点击Home无法复原,一直处于OverviewMode模式,无法退出。造成这个问题的原因是

因为Launcher中的hideAppsCustomizeHelper方法判断是否需要退出OverviewMode模式时, boolean initialized = get

AllAppsButton() != null;这里这个参数会一直都是false,以为赋值给该参数的方法判定条件是!LauncherAppState.isDis

ableAllApps(),我修改了这里永远返回true。所以我们从新修改hideAppsCustomizeHelper方法中退出OverviewMode

模式的条件即可。同时也把showAppsCustomizeHelper中的判断方法的initialized 去掉去掉。以免造成不必要的麻烦

 /**
     * Zoom the camera back into the workspace, hiding 'fromView'.
     * This is the opposite of showAppsCustomizeHelper.
     * @param animated If true, the transition will be animated.
     */
    private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,
            final boolean springLoaded, final Runnable onCompleteRunnable) {

        if (mStateAnimation != null) {
            mStateAnimation.setDuration(0);
            mStateAnimation.cancel();
            mStateAnimation = null;
        }

        boolean material = Utilities.isLmpOrAbove();
        Resources res = getResources();

        final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);
        final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);
        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);
        final int itemsAlphaStagger =
                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);

        final float scaleFactor = (float)
                res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);
        final View fromView = mAppsCustomizeTabHost;
        final View toView = mWorkspace;
        Animator workspaceAnim = null;
        final ArrayList<View> layerViews = new ArrayList<View>();

        if (toState == Workspace.State.NORMAL) {
            workspaceAnim = mWorkspace.getChangeStateAnimation(
                    toState, animated, layerViews);
        } else if (toState == Workspace.State.SPRING_LOADED ||
                toState == Workspace.State.OVERVIEW) {
            workspaceAnim = mWorkspace.getChangeStateAnimation(
                    toState, animated, layerViews);
        }

        // If for some reason our views aren't initialized, don't animate
        boolean initialized = getAllAppsButton() != null;

        /**
         * 修改此处,解决长按空白处显示修改壁纸后点击Home键无法恢复的bug
         *
         * 因为在HotSeat方法中的setAllAppsButton()的条件是!LauncherAppState.isDisableAllApps()
         *
         * 修改默认返回为true后,就不会总setAllAppsButton的方法,所以getAllAppsButton()永远为空
         *
         */

//        if (animated && initialized) {
        if (animated ) {
            mStateAnimation = LauncherAnimUtils.createAnimatorSet();
            if (workspaceAnim != null) {
                mStateAnimation.play(workspaceAnim);
            }

            final AppsCustomizePagedView content = (AppsCustomizePagedView)
                    fromView.findViewById(R.id.apps_customize_pane_content);

 

<think>好的,我现在需要帮助用户找到关于Android实现按桌面进入编辑模式的方法。根据用户提供的引用内容,我需要仔细分析已有的信息,并从中提取相关的实现方法。 首先,用户引用了几个关于Android Launcher3修改,比如按图标弹出快捷方式、拖拽抖动动画、去掉应用信息按钮等。这些引用中提到了相关的代码位置和关键类,比如WorkspaceLayoutManager.java、ItemLongClickListener.java、DragController.java等。这些可能涉及到按事件的处理,而编辑模式的触发很可能也是通过按事件来实现的。 引用[4]中提到,在WorkspaceLayoutManager.java的addInScreen方法中,设置了child.setOnLongClickListener,这说明按事件的监听器是在这里设置的。ItemLongClickListener负责处理按事件,所以用户需要在这里修改按的行为,可能是在ItemLongClickListener中判断按动作,并触发编辑模式。 引用[2]和[4]都提到了拖拽抖动动画的实现,这可能与进入编辑模式后的UI效果有关。编辑模式通常允许用户拖动图标、删除应用或调整布局,所以需要启动拖拽操作并改变图标状态,比如抖动动画。DragController.java可能控制拖拽的开始和结束,因此进入编辑模式可能需要在这里初始化拖拽状态,并显示编辑相关的选项。 引用[3]提到修改SystemShortcutFactory来移除应用信息按钮,这说明系统快捷菜单可以通过修改这些工厂类来自定义选项。如果用户想在按桌面时进入编辑模式,可能需要在这里添加新的快捷方式或替换现有的选项,比如添加一个“编辑模式”按钮。 引用[5]中的双指按返回桌面的方法,虽然与当前问题不同,但展示了如何在系统手势监听器中添加自定义的按行为。不过,用户的问题是关于桌面的按,所以应该集中在Launcher3的处理上,而不是全局手势。 综合这些信息,实现按桌面进入编辑模式的步骤可能包括: 1. **修改按事件监听器**:在ItemLongClickListener中检测到按事件时,判断触发条件是否为桌面(Workspace),如果是,则启动编辑模式。 2. **进入编辑模式的状态管理**:可能需要一个标志位来标识当前是否处于编辑模式,并触发相应的UI变化,如图标抖动、显示删除按钮等。 3. **拖拽控制与动画**:参考拖拽抖动动画的实现,在进入编辑模式时启动动画,允许用户拖拽图标,并在退出编辑模式时停止动画。 4. **自定义快捷菜单**:可能需要修改SystemShortcutFactory,添加编辑模式相关的选项,或者在按时直接跳转到编辑模式,而不是弹出默认菜单。 需要注意,Launcher3的代码结构可能因版本而异,用户需要根据自己项目的Android版本调整具体的类和方法。例如,引用[4]提到Android 13的实现,而其他引用涉及不同版本,因此需要确认代码是否匹配。 可能的实现步骤包括: - 在ItemLongClickListener的onLongClick方法中,判断当前按的位置是否为桌面区域,如果是,则调用进入编辑模式的方法。 - 在Workspace或相关类中,添加enterEditMode()方法,该方法触发图标的抖动动画,并允许拖拽操作。 - 修改DragController,使其在编辑模式下允许拖拽并显示相关控件。 - 可能需要调整WorkspaceLayoutManager的布局逻辑,以支持编辑模式下的特殊布局,比如显示删除区域。 用户可能需要参考引用[2]和[4]中拖拽动画的实现,将其应用到编辑模式的触发中。同时,需要确保在进入编辑模式后,正确处理触摸事件和手势,避免与其他操作冲突。 此外,引用[1]提到快捷方式的配置需要在主Activity中设置,但用户的问题是关于桌面(Launcher)的按,所以主要修改的是Launcher3的代码,而不是应用的Activity。因此,关注点应放在Launcher3的相关类上。 总结来说,关键点在于捕获按事件,触发编辑模式的状态变化,并管理相应的UI和交互逻辑。需要结合现有的按处理和拖拽机制进行扩展。</think>在Android系统中实现按桌面进入编辑模式,主要涉及Launcher3应用层的事件监听与状态控制。以下是基于引用内容整理的核心实现方法: --- ### **实现步骤** 1. **按事件监听配置** 在`WorkspaceLayoutManager.java`的`addInScreen()`方法中,为桌面图标设置按监听器: ```java child.setOnLongClickListener(ItemLongClickListener.INSTANCE_WORKSPACE); ``` 需修改`ItemLongClickListener.java`的`onLongClick()`方法,判断是否为桌面空白区域按[^4]。 2. **触发编辑模式状态** 在按事件中调用进入编辑模式的方法(如`enterEditMode()`),通常通过`Workspace`或`Launcher`类管理状态: ```java public void enterEditMode() { mIsEditMode = true; startShakeAnimation(); // 启动图标抖动动画 showDeleteZone(); // 显示删除区域 } ``` 参考拖拽动画的实现逻辑(`DragController.java`和Workspace的UI控制)[^2][^4]。 3. **编辑模式交互控制** - **拖拽操作**:在`DragController.java`中修改拖拽逻辑,允许在编辑模式下自由移动图标。 - **退出编辑**:监听点击空白区域或返回键,调用`exitEditMode()`重置状态并停止动画。 --- ### **关键代码修改示例** 1. **修改`ItemLongClickListener.java`** ```java public class ItemLongClickListener { public static final OnLongClickListener INSTANCE_WORKSPACE = (v) -> { // 判断是否为桌面空白区域按 if (v instanceof Workspace) { getLauncher(v.getContext()).enterEditMode(); return true; } // 原有图标按逻辑 return startDrag(v); }; } ``` 2. **添加编辑模式状态管理** 在`Launcher.java`中增加状态标志与动画控制: ```java public void enterEditMode() { mWorkspace.startShakeAnimation(); mDragController.setEditMode(true); } public void exitEditMode() { mWorkspace.stopShakeAnimation(); mDragController.setEditMode(false); } ``` --- ### **适配不同Android版本** - **Android 10+**:需注意`SystemShortcutFactory`的修改,避免与原快捷菜单冲突(如移除默认按钮)[^3]。 - **动态权限**:若涉及敏感操作(如卸载应用),需动态申请权限。 --- ### **效果验证** 1. 按桌面空白区域触发图标抖动动画。 2. 可拖拽图标到删除区域完成卸载。 3. 按返回键或点击空白区域退出编辑模式。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值