当前位置: 首页 > wzjs >正文

排名sem优化软件泉州网站优化排名

排名sem优化软件,泉州网站优化排名,牛牛襄阳网站建设,常见网站建设公司术语这里强调的是手势模式下,三按钮模式不在本文讨论范围内。 手势模式下,我们可以在Launcher桌面的底部使用手势上滑停顿进最近任务,或者在第三方应用底部上滑进最近任务。 这两种场景是手势模式底部上滑的两种常见场景,本文来讨论…

这里强调的是手势模式下,三按钮模式不在本文讨论范围内。

手势模式下,我们可以在Launcher桌面的底部使用手势上滑停顿进最近任务,或者在第三方应用底部上滑进最近任务。

这两种场景是手势模式底部上滑的两种常见场景,本文来讨论一下这两种场景的流程和原理。

第三方应用(非Launcher)底部上滑

在这里插入图片描述

Launcher底部上滑

在这里插入图片描述

TouchInteractionService

Launcher中提到底部上滑,绕不开TouchInteractionService这个类。
这个类是Launcher中的一个核心类,是一个Service,在Launcher3启动的时候会加载的服务。
里面会对输入事件进行监听,最终在onInputEvent回调方法中对事件进行分发处理。

private void onInputEvent(InputEvent ev) {if (!(ev instanceof MotionEvent)) {ActiveGestureLog.INSTANCE.addLog(new CompoundString("TIS.onInputEvent: ").append("Cannot process input event, received unknown event ").append(ev.toString()));return;}MotionEvent event = (MotionEvent) ev;}

这里首先对事件进行判断,确保是触摸事件。

接着在ACTION_DOWN的时候会确认事件的消费者。

  if (action == ACTION_DOWN || isHoverActionWithoutConsumer) {mRotationTouchHelper.setOrientationTransformIfNeeded(event);boolean isOneHandedModeActive = mDeviceState.isOneHandedModeActive();boolean isInSwipeUpTouchRegion = mRotationTouchHelper.isInSwipeUpTouchRegion(event);if ((!isOneHandedModeActive && isInSwipeUpTouchRegion)|| isHoverActionWithoutConsumer) {reasonString.append(!isOneHandedModeActive && isInSwipeUpTouchRegion? "one handed mode is not active and event is in swipe up region": "isHoverActionWithoutConsumer == true").append(", creating new input consumer");// Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger// onConsumerInactive and wipe the previous gesture stateGestureState prevGestureState = new GestureState(mGestureState);GestureState newGestureState = createGestureState(mGestureState,getTrackpadGestureType(event));newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis());mConsumer.onConsumerAboutToBeSwitched();mGestureState = newGestureState;mConsumer = newConsumer(prevGestureState, mGestureState, event);mUncheckedConsumer = mConsumer;}

这里有一句非常重要的代码

mConsumer = newConsumer(prevGestureState, mGestureState, event);

这里根据系统的整体情况,会创建不同的consumer。
这里的consumer就是对触摸事件最终处理的消费者。
在Launcher3中,有多种Consumer,针对不同的情况。本文提到的两种场景,就涉及到其中的两种,分别是OtherActivityConsumer和OverviewInputConsumer
在这里插入图片描述
整个Launcher3中还有多种consumer,根据不同的场景,可以找到对应的consumer,这里不再赘述。
总之,可以明确的一点是,前面提到的两个场景分别对应的是OtherActivityConsumer和OverviewInputConsumer。
下面分别来介绍这两个重要的类。

OtherActivityConsumer

  • 核心作用: 负责处理起始于非 Launcher 活动窗口(即“Other Activity”)的上滑手势。这是实现从应用返回桌面、进入概览(最近任务)或进行快速切换(左右滑动切换任务)的主要入口。
  • 关键职责:
    • 启动/继续 Recents 动画: 当手势开始时,它负责通过 TaskAnimationManager 启动或继续一个 RecentsAnimation。这个动画允许 Launcher 控制应用窗口的 Surface。
    • 创建和管理 AbsSwipeUpHandler: 它是实际处理手势逻辑和动画细节的核心。OtherActivityInputConsumer 会创建一个 AbsSwipeUpHandler (的具体子类实例,如 LauncherSwipeHandlerV2),并将触摸事件传递给它。
    • 手势追踪与状态判断: 使用 VelocityTracker 追踪手指速度,结合 MotionPauseDetector 检测手势是否暂停,判断用户的意图(去 Home、去 Recents、切换任务等)。
    • 事件拦截 (Pilfering): 一旦确认用户正在进行手势导航(超过 TouchSlop),它会调用 mInputMonitorCompat.pilferPointers() 来拦截后续的触摸事件,防止这些事件传递给下方的应用窗口。
    • 协调 AbsSwipeUpHandler: 将计算出的位移、速度传递给 AbsSwipeUpHandler,由后者驱动窗口和 Launcher UI 的动画。
    • 生命周期管理: 管理自身和 AbsSwipeUpHandler 的状态,并在手势完成或被取消时通知系统(通过 mOnCompleteCallback)。
  • 使用场景:
    • 用户在任何第三方应用或系统应用(非 Launcher)界面,从屏幕底部边缘向上滑动时。 这是最常见的场景,涵盖了:
      • 上滑返回桌面 (Go Home)。
      • 上滑并暂停进入概览/最近任务 (Enter Overview/Recents)。
      • 上滑并快速左右滑动切换到上一个/下一个应用 (Quick Switch)。

OverviewInputConsumer

  • 核心作用: 负责处理发生在 Launcher/概览活动界面内的输入事件。当用户已经在与 Launcher 的 UI(如 RecentsView 中的任务卡片、主屏幕背景等)交互时,这个消费者会被激活。
  • 关键职责:
    • 事件代理/转发: 它的主要工作是将接收到的触摸事件 (onMotionEvent) 转发给 Launcher 的 DragLayer (mTarget.proxyTouchEvent)。它本质上是一个事件传递者
    • 坐标转换: 在转发事件前,会调整事件坐标,使其相对于 DragLayer
    • 处理其他输入: 可以处理悬停事件 (onHoverEvent) 和按键事件 (onKeyEvent),并将它们分发给 Launcher Activity。对于按键,它可能会处理特定的按键(如音量键、方向键的焦点处理)。
    • 选择性拦截: 如果触摸事件起始于屏幕边缘但在活动范围内被 DragLayer 处理了 (mTargetHandledTouch 变为 true),它也会调用 mInputMonitor.pilferPointers(),确保 Launcher 完全接管事件处理。
  • 使用场景:
    • 用户已经在概览/最近任务界面时:
      • 点击某个任务卡片来启动应用。
      • 在任务卡片上进行滑动操作(例如,上滑清除任务)。
      • 左右滑动浏览不同的任务卡片。
      • 点击概览界面上的其他按钮或空白区域。
    • 在返回桌面的过渡动画中与 Launcher 交互: 当用户从应用返回桌面,动画正在进行时,如果用户触摸到 Launcher 的某个元素(如图标),OverviewInputConsumer 会接管事件处理。
    • 键盘导航: 处理在概览界面中的键盘焦点和导航事件。

两个Consumer的主要区别总结:

特性OtherActivityInputConsumerOverviewInputConsumer
事件起始位置非 Launcher/概览 活动窗口Launcher/概览 活动窗口内部
核心功能启动和管理手势导航动画与逻辑代理和转发输入事件给 Launcher UI
动画控制主动驱动窗口和 Launcher UI 动画 (通过 Handler)不直接控制窗口动画,依赖 Launcher 自身处理
事件处理方式解释事件用于手势状态判断和动画进度控制转发事件DragLayerActivity
交互对象AbsSwipeUpHandler, RecentsAnimationControllerDragLayer, Activity
主要目的实现从 外部应用 进入 Launcher/概览/切换任务处理在 Launcher/概览内部 的用户交互

两个场景的区别

这两个场景看上去都是进入了最近任务,但是区别还是很大的。
通过第三方应用进入最近任务,如果这个第三方应用是一个视频应用,例如爱奇艺在播放视频,你会发现,在进入最近任务后,爱奇艺仍然在播放视频,中间的任务是动态实时展示的。
而通过Launcher底部进入最近任务,中间的任务是静态的,展示的是应用的截图。

在这里插入图片描述
在这里插入图片描述
为什么出现这两种情况?这是由于这两种场景完全不同的实现方式决定的。
前一种情况,简单的说,第三方应用底部缩放的时候是将应用本身进行缩放,然后通过RemoteAnimationTarget将应用的画面模拟成task的样子显示在最近任务中,实际上,显示的画面是应用画面且实时更新的。
这一部分可以从AbsSwipeUpHandler的核心方法apply中看出来,代码如下:

//aosp/packages/apps/Launcher3/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.javaprotected void applyScrollAndTransform() {// No need to apply any transform if there is ongoing swipe-to-home animator//    swipe-to-pip handles the leash solely//    swipe-to-icon animation is handled by RectFSpringAnim animboolean notSwipingToHome = mRecentsAnimationTargets != null&& mGestureState.getEndTarget() != HOME;boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;float progress = Math.max(mCurrentShift.value, getScaleProgressDueToScroll());int scrollOffset = setRecentsScroll ? mRecentsView.getScrollOffset() : 0;Log.i("yy_log", "AbsSwipeUpHandler#applyScrollAndTransform, notSwipingToHome: " + notSwipingToHome+ ", setRecentsScroll: " + setRecentsScroll + ", progress: " + progress + ", scrollOffset: " + scrollOffset, new Exception());if (!mStartMovingTasks && (progress > 0 || scrollOffset != 0)) {mStartMovingTasks = true;startInterceptingTouchesForGesture();}for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {AnimatorControllerWithResistance playbackController =remoteHandle.getPlaybackController();if (playbackController != null) {playbackController.setProgress(progress, mDragLengthFactor);}if (notSwipingToHome) {// 进入最近任务TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();if (setRecentsScroll) {taskViewSimulator.setScroll(scrollOffset);}//将第三方应用的画面模拟成taskviewtaskViewSimulator.apply(remoteHandle.getTransformParams());}}}

后一种情况,前面我们看到的是走的OverviewInputConsumer,这种情况下,最终会将触摸事件代理到BaseDragLayer,proxyTouchEvent里面会去寻找touchController,如下代码:
mProxyTouchController = findControllerToHandleTouch(ev);

07-04 22:01:05.140  3310  3310 I yy_log  : BaseDragLayer#proxyTouchEvent, mProxyTouchController: com.android.launcher3.uioverrides.touchcontrollers.NoButtonNavbarToOverviewTouchController@ae19028

这里打个日志,可以看到最终找到的Controller是NoButtonNavbarToOverviewTouchController
最终在手势停止的时候回调onMotionPauseDetected方法,进入OVERVIEW状态。因此,这个场景与上面的是完全不同的两个场景,虽然最终看上去都是进入了最近任务页面。

    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);}

文章转载自:

http://rGdszrG3.qstjr.cn
http://aF9RqWMR.qstjr.cn
http://UblDslUs.qstjr.cn
http://4RZye43U.qstjr.cn
http://cRJh8W6y.qstjr.cn
http://wpXLV8SZ.qstjr.cn
http://vtP8WVuh.qstjr.cn
http://KAYnaQCd.qstjr.cn
http://2UsfPDOa.qstjr.cn
http://LuV9wvIe.qstjr.cn
http://wdUqrjJH.qstjr.cn
http://W0gdEyyH.qstjr.cn
http://f48bvrbl.qstjr.cn
http://MFOgg107.qstjr.cn
http://23FfSHIo.qstjr.cn
http://IXR9YiTn.qstjr.cn
http://MF6IbiHF.qstjr.cn
http://HyVXXCtU.qstjr.cn
http://E6ofD7Nj.qstjr.cn
http://oFaamciJ.qstjr.cn
http://JphCV1nK.qstjr.cn
http://yWmQKAym.qstjr.cn
http://cqpuKlsx.qstjr.cn
http://rrLuNdLI.qstjr.cn
http://SrsTPIrM.qstjr.cn
http://WrtqDrM9.qstjr.cn
http://eeiopzMj.qstjr.cn
http://ooeAbFSl.qstjr.cn
http://tiapYmUg.qstjr.cn
http://iAkRYFyY.qstjr.cn
http://www.dtcms.com/wzjs/673457.html

相关文章:

  • 如何制作网站视频教程西安计算机培训机构排名前十
  • 深圳微商城网站设计公司做网站有的浏览器
  • 无法进行网站备案企业网站建设规划 论文
  • 郑州快速网站优化公司哪家好上海市建设工程 安全质量网站
  • 空包网站建设属于哪类怎么做集团网站
  • 求做外宣图网站wordpress取消更改
  • 做网站做本地服务器吗环境没有tomcat怎么演示自己做的网站
  • 网站流量图片生成哪有做网站
  • 想让网站的文章都被收录怎么做转入已备案网站
  • 青海住房城乡建设厅网站市场监督管理局官网入口
  • 做网站域名需要在哪里备案网站建设的源代码
  • 茂名网站开发公司永久免费自助建站平台
  • 宁波做网站皆选蓉胜网络手机版wordpress怎么用
  • 寻找电子商务网站建设外贸网站营销推广
  • 建网站需要学习什么网站快速收录平台
  • 天津网站制作价格手机网站引导页js
  • 网站开发容易吗织梦同时运行多个网站
  • 中国人免费的片宁波网站优化如何
  • 沈阳营销型网站制作网页版微信可以传文件吗
  • 汝州住房和城乡建设局网站免费建视频网站
  • 网站建设总流程莱山做网站的公司
  • 企业电子商务网站开发实训目的wordpress开启加载图标库
  • 网站开发哪方面好做龙华做棋牌网站建设哪家便宜
  • 网站怎么设计制作wordpress代码增强插件
  • 西部数码网站管理助手 伪静态专业团队建设实施方案
  • 广州建设工程交易中心网站idzoom室内设计师网
  • 南京酒店网站制作网站头部 标签
  • 上海网站网络科技有限公司昆山app网站制作
  • 兰州市城乡和住房建设局网站店面设计师岗位职责
  • 广州网站平台建设做网站合同范本