launcher功能入口(三)

背景描述

本篇文章补充一下之前https://blog.csdn.net/a396604593/article/details/123487805文章中的一些没填上的坑。
此代码基于Android 12

上篇:Launcher功能入口
上篇:launcher功能入口(二)
本篇:launcher功能入口(三)

Launcher滑动分析

10、上滑进入recent
packages\apps\Launcher3\quickstep\src\com\android\launcher3\uioverrides\touchcontrollers\NoButtonNavbarToOverviewTouchController.java

public void onDragStart(boolean start, float startDisplacement) {
		if (handlingOverviewAnim()) {//判断是否拦截
			//设置停顿监听
            mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
        }
}
	//mDidTouchStartInNavBar赋值
    @Override
    protected boolean canInterceptTouch(MotionEvent ev) {
        mDidTouchStartInNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
        return super.canInterceptTouch(ev);
    }
    //判断时在底部上滑,并且在主界面
    private boolean handlingOverviewAnim() {
        int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
        return mDidTouchStartInNavBar && mStartState == NORMAL
                && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
    }
//运动暂停检测,recent的触发是底部上滑并且停顿了一下,就会进入recent界面(Android 12,之前版本的recent触发有所不同)
mMotionPauseDetector.addPosition(event);
//取消mCurrentAnimation动画,进入recent
private void onMotionPauseDetected() {
        if (mCurrentAnimation == null) {
            return;
        }
        mNormalToHintOverviewScrimAnimator = null;
        mCurrentAnimation.getTarget().addListener(newCancelListener(() ->
                mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> {
                    mOverviewResistYAnim = AnimatorControllerWithResistance
                            .createRecentsResistanceFromOverviewAnim(mLauncher, null)
                            .createPlaybackController();
                    mReachedOverview = true;
                    maybeSwipeInteractionToOverviewComplete();
                }))));

        mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
        mCurrentAnimation.dispatchOnCancel();
        mStartedOverview = true;
        VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
    }

12、上滑进入all apps
1、packages\apps\Launcher3\src\com\android\launcher3\touch\BaseSwipeDetector.java
处理触摸滚动事件

public boolean onTouchEvent(MotionEvent ev) {...}

2、packages\apps\Launcher3\src\com\android\launcher3\touch\AbstractStateChangeTouchController.java
中判断滑动距离或者速度,决定进入或者不进入allapps

public void onDragEnd(float velocity) {
...
		if (fling) {
            targetState =
                    Float.compare(Math.signum(velocity), Math.signum(mProgressMultiplier)) == 0
                            ? mToState : mFromState;
            // snap to top or bottom using the release velocity
        } else {
            targetState =
                    (interpolatedProgress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
        }
...
}

注意:mCurrentAnimation动画负责进入退出all apps
没有直接调用packages\apps\Launcher3\src\com\android\launcher3\statemanager\StateManager.java中的goToState方法。

12.1、上滑进入应用列表界面透明度变化

packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsTransitionController.java
setAlphas中处理

12.2、快速滑动进入退出allapps界面速度分析
packages/apps/Launcher3/src/com/android/launcher3/touch/SwipeDetector.java

private void reportDragEnd() {
    mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);//速度计算,计算一秒滑过多少像素
    float velocity = mDir.getVelocity(mVelocityTracker, mIsRtl) / 1000;//一秒钟滑动过多少k像素
    if (DBG) {
        Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f",
                mDisplacement, velocity));
    }
    //
    mListener.onDragEnd(velocity, Math.abs(velocity) > RELEASE_VELOCITY_PX_MS);//传入速度和速递阈值判断,速度大于1k 才认为是fling
}

packages/apps/Launcher3/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java

onDragEnd根据参数判断是否是fling 如果是 则进入或者退出allapps, 如果不是 判断动画距离是否过半,如果超过0.5f 则改变状态,否则回到上一个状态

13、桌面下拉显示通知栏
packages\apps\Launcher3\quickstep\src\com\android\launcher3\uioverrides\touchcontrollers\StatusBarTouchController.java
StatusBarTouchController拦截滑动事件并传递给systemui

//事件拦截
private boolean canInterceptTouch(MotionEvent ev) {...}
//事件分发
private void dispatchTouchEvent(MotionEvent ev) {
        if (mSystemUiProxy.isActive()) {
            mLastAction = ev.getActionMasked();
            mSystemUiProxy.onStatusBarMotionEvent(ev);
        }
    }
触摸事件流程总结

1、触摸事件的根是从packages\apps\Launcher3\src\com\android\launcher3\dragndrop\DragLayer.java分发下来。
packages\apps\Launcher3\src\com\android\launcher3\views\BaseDragLayer.java中找到处理事件对应的controller
然后由具体的controller处理滑动事件。

private TouchController findControllerToHandleTouch(MotionEvent ev) {
        AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
        if (topView != null
                && (isEventInLauncher(ev) || topView.canInterceptEventsInSystemGestureRegion())
                && topView.onControllerInterceptTouchEvent(ev)) {
            return topView;
        }

        for (TouchController controller : mControllers) {
            if (controller.onControllerInterceptTouchEvent(ev)) {
                Log.d("TouchController","TouchController: "+controller);
                return controller;
            }
        }
        return null;
    }

2、TouchController 接口,主要关注onControllerTouchEvent和onControllerInterceptTouchEvent方法。
触摸事件都在TouchController的实现类中进行。比较多,这里就不贴出来了

public interface TouchController {
    /**
     * Called when the draglayer receives touch event.
     */
    boolean onControllerTouchEvent(MotionEvent ev);
    /**
     * Called when the draglayer receives a intercept touch event.
     */
    boolean onControllerInterceptTouchEvent(MotionEvent ev);
    /**
     * Called when one handed mode state changed
     */
    default void onOneHandedModeStateChanged(boolean activated) { }
    default void dump(String prefix, PrintWriter writer) { }
}

3、launcher中滑动处理比较多,有时候找不到对应的处理逻辑。
要忽略复杂多变的实现类,从事件传递根或者重要接口出发,判断是哪个实现类拦截处理了触摸事件。
然后再找具体的拦截判断和触摸事件处理逻辑

implements TouchController, SingleAxisSwipeDetector.Listener
InputConsumer输入事件

https://blog.csdn.net/a396604593/article/details/123487805中
11、三方应用界面上滑返回launcher
简单写了一下三方应用界面上滑launcher怎么处理输入事件。
跟踪此类问题和触摸事件类似,实现类比较多,要多关注接口。有一个整体的逻辑之后再看具体的处理

也可以看一下其它人写的https://blog.csdn.net/tq501501/article/details/120002676还不错。

16、主屏幕设置–通知圆点

有时候通知圆点显示三角形,没有默认赋予权限。
配置config_defaultListenerAccessPackages即可,framework下面的不生效需要查一下是否gms包覆盖掉了:
vendor/partner_gms/overlay/GmsConfigOverlayCommon/res/values/config.xml

    <!-- Colon separated list of package names that should be granted Notification Listener access -->
    <string name="config_defaultListenerAccessPackages" translatable="false">com.android.launcher3:com.google.android.projection.gearhead</string>

临时验证:

adb shell  settings put secure enabled_notification_listeners com.google.android.projection.gearhead/com.google.android.gearhead.notifications.SharedNotificationListenerManager$ListenerService:com.android.launcher3/com.android.launcher3.notification.NotificationListener

之前写过一点流程,忘记了,这里加一个跳转链接https://blog.csdn.net/a396604593/article/details/128025161

17 、widget大小调整框

AppWidgetResizeFrame.showForWidget
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值