AOSP Android14 Launcher3——底部任务栏Taskbar详解

种地  论坛元老 | 2025-4-16 11:12:03 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1699|帖子 1699|积分 5097

媒介:Launcher3中底部Taskbar和Navbar,或者说中文内里的术语导航栏,这几个词是很容易让人肴杂的地方。本文要先容的是Taskbar。从字面上意思来看,Taskbar就是任务栏,任务栏是Launcher3中一个重要的组件,尤其是在大屏平板设备上。
  Taskbar的UI 形态

Taskbar在Launcher3中到底是指哪部分?
直接上图:



在屏幕底部显示的带有应用图标的部分就是Taskbar中的一部分,从上面LayoutInspector中可以看到,底部高度为161dp的View就是Taskbar。
在Launcher中,Taskbar的视图类是TaskbarDragLayer。
Taskbar有两种状态,一种是上图中完全展开的形态,有个术语叫UnStash状态,另有一种是只有底部一个bar条的形态,这种叫Stash状态。

Taskbar的显示逻辑与流程

核心目的:

Taskbar 旨在为大屏幕设备(平板电脑、折叠屏)提供类似桌面操纵系统的体验,在应用运行时提供一个常驻或可按需访问的应用启动器和导航栏。
关键组件和控制器:


  • TaskbarManager.java: 这是 Taskbar 的全局管理器

    • 职责: 决定是否应该在当前设备和设置下启用 Taskbar。监听设备状态变革(如屏幕旋转、折叠状态、导航模式切换)来判断是否需要创建或销毁 Taskbar UI。
    • 流程: 当 TaskbarManager 确定需要 Taskbar 时(通常在 LauncherActivity 或类似上下文启动时),它会创建 TaskbarActivityContext。

  • TaskbarActivityContext.java: Taskbar 的上下文环境

    • 职责: 这是 Taskbar UI 现实运行的 Context。它负责创建 Taskbar 的主视图(TaskbarView)和 DragLayer (TaskbarDragLayer),并初始化所有的 Taskbar 控制器 (TaskbarControllers)。它还处理与 Launcher Activity 的生命周期绑定、资源获取、权限查抄等。
    • 流程:

      • 在 onCreate() 中,它会加载 Taskbar 布局 (R.layout.taskbar)。
      • 创建 TaskbarControllers 实例,该实例会聚合所有其他的子控制器。
      • 调用 TaskbarControllers.init() 来初始化所有子控制器,并创建它们之间的引用。


  • TaskbarControllers.java: 控制器聚合器

    • 职责: 持有所有其他 Taskbar 子控制器的引用,方便它们之间相互访问和协调。提供一个同一的初始化 (init) 和销毁 (onDestroy) 入口。
    • 流程: 在 init() 中,它会按次序创建并初始化各个子控制器,如 TaskbarViewController、TaskbarStashController、NavbarButtonsViewController 等。

  • TaskbarView.java: 核心 UI 视图

    • 职责: 继承自 ViewGroup,是容纳 Taskbar 上所有图标(应用、文件夹、猜测应用)的容器。它处理图标的布局、添加、移除和更新。
    • 显示: 由 TaskbarActivityContext 创建并添加到其 TaskbarDragLayer 中。

  • TaskbarViewController.java: TaskbarView 的控制器

    • 职责: 管理 TaskbarView 的内容和视觉状态。

      • 从数据模子(通过 TaskbarModelCallbacks)获取应用列表并绑定到 TaskbarView 上。
      • 处理图标的点击、长按(弹出菜单,通过 TaskbarPopupController)。
      • 控制图标的 Alpha、Scale、TranslationY 等属性,用于共同 TaskbarStashController 实现收起/展开动画。

    • 流程: 在 TaskbarControllers.init() 中被初始化,并获取对 TaskbarView 的引用。监听数据模子变革来更新 UI。

  • TaskbarStashController.java: 收起/展开逻辑的核心控制器

    • 职责: 这是控制 Taskbar 是否应该显示为完整条、收起成一个细条 (Handle) 或完全隐藏的决议中心和动画协调者
    • 原理 (State Flags): 维护一个整数状态 mState,通过位标志 (FLAG_*) 来记载各种影响 Taskbar 可见性的条件,例如:

      • FLAG_IN_APP: 是否在第三方应用中。
      • FLAG_STASHED_IN_APP_SYSUI: 系统 UI(如通知面板)是否要求收起。
      • FLAG_STASHED_IN_APP_IME: 输入法是否显示。
      • FLAG_IN_STASHED_LAUNCHER_STATE: 当前 Launcher 状态是否要求收起 (如 AllApps)。
      • FLAG_STASHED_IN_APP_AUTO: 是否是瞬态 Taskbar (Transient) 且当前处于自动隐藏状态。
      • FLAG_STASHED_DEVICE_LOCKED: 设备是否锁定。
      • … 等等。

    • 决议 (mIsStashedPredicate): 通过一个 IntPredicate (一个函数式接口,输入 int 返回 boolean) 来判断当前 mState 的组合是否意味着 Taskbar 应该处于收起状态 (mIsStashed)。
    • 状态应用 (applyState, createApplyStateAnimator): 当外部事件(如 Launcher 状态改变、系统 UI 状态改变、用户交互等)调用 updateStateForFlag() 更新了 mState 后,会调用 applyState()。applyState() 会比较新的预期收起状态 (mIsStashedPredicate.test(newState)) 和当前的视觉状态 (mIsStashed)。

      • 假如状态不一致,则调用 createAnimToIsStashed() 创建一个 AnimatorSet 来驱动 Taskbar UI 元素的动画(背景、图标、Handle 的 Alpha、Scale、Translation)。
      • 动画会平滑地过渡到新的收起/展开状态。

    • 动画范例 (@StashAnimation): 支持多种差别的收起/展开动画效果(TRANSITION_DEFAULT, TRANSITION_HOME_TO_APP, TRANSITION_HANDLE_FADE 等),根据触发场景选择差别的动画插值器和时序。
    • 瞬态 Taskbar (Transient): 对瞬态 Taskbar 有特殊处理逻辑,包括自动隐藏计时器 (mTimeoutAlarm) 和通过 updateAndAnimateTransientTaskbar() 进行显式控制。

  • StashedHandleViewController.java & StashedHandleView.java: 收起状态 Handle 的控制器和视图

    • 职责: 当 TaskbarStashController 决定收起 Taskbar 时,StashedHandleViewController 负责显示和管理 StashedHandleView(那个白色细条)。它控制 Handle 的 Alpha 和 Scale,实现显示/隐藏以及 Hint 动画(轻微放大提示可以展开)。

  • TaskbarLauncherStateController.java: Launcher 状态转换器

    • 职责: 监听 Launcher 的状态变革(StateManager.addStateListener),并将 Launcher 状态(如 NORMAL, OVERVIEW, ALL_APPS)转换为 TaskbarStashController 能明确的状态标志 (FLAG_IN_STASHED_LAUNCHER_STATE, FLAG_IN_APP, FLAG_IN_OVERVIEW)。
    • 流程: 当 Launcher 状态切换时,它会调用 TaskbarStashController.updateStateForFlag() 来更新相应的标志,然后触发 TaskbarStashController.applyState() 来应用变革。

  • TaskbarInsetsController.kt: 窗口 Insets 控制器

    • 职责: 根据 Taskbar 的收起/展开状态和范例(持久/瞬态),计算应该向应用陈诉的窗口 Insets(底部导航栏地区)。
    • 原理: 当 Taskbar 展开时,陈诉完整的高度;当收起时,通常陈诉 mStashedHeight(Handle 的高度),或者在某些特定情况(如持久 Taskbar + IME)下陈诉 0。它确保应用的内容能够正确地避让 Taskbar。

  • TaskbarStashViaTouchController.kt: 触摸交互控制器

    • 职责: 处理用户直接在 Stashed Handle 或 Taskbar 背景地区的触摸事件,用于触发/取消瞬态 Taskbar 的自动隐藏计时器,或者启动 Hint 动画。

  • 其他控制器:

    • NavbarButtonsViewController.java: 管理导航按钮(Back, Home, Recents)的显示、布局和点击事件。
    • TaskbarDragLayerController.java: 管理 Taskbar 的背景、圆角和 Y 轴偏移。
    • TaskbarDragController.java: 处理 Taskbar 内部或涉及 Taskbar 的拖放操纵。
    • TaskbarKeyguardController.java: 处理锁屏状态对 Taskbar 的影响。
    • TaskbarPinningController.kt: 处理用户固定/取消固定持久 Taskbar 的设置。
    • TaskbarAutohideSuspendController.java: 管理自动隐藏功能的停息状态。
    • … 等等。

加载与显示流程总结:


  • 启动: LauncherActivity (或其他宿主) 启动。
  • TaskbarManager 决议: TaskbarManager 判断当前设备设置是否需要 Taskbar。
  • 创建 Context: 假如需要,TaskbarManager 创建 TaskbarActivityContext。
  • Context 初始化: TaskbarActivityContext 加载布局,创建 TaskbarDragLayer 和 TaskbarView。
  • 控制器聚合: TaskbarActivityContext 创建 TaskbarControllers。
  • 子控制器初始化: TaskbarControllers.init() 逐个创建并初始化所有子控制器 (TaskbarViewController, TaskbarStashController, NavbarButtonsViewController 等),并创建它们之间的引用。
  • 初始状态设定:

    • TaskbarStashController 根据初始条件(是否 Setup、是否 Phone Mode、是否瞬态、持久化设置等)设置初始的 mState 标志。
    • TaskbarLauncherStateController 获取当前的 Launcher 状态,并更新 TaskbarStashController 的相应标志。

  • 初次应用状态: TaskbarStashController.applyState(0) 被调用,根据初始的 mState 计算出 Taskbar 应该是收起照旧展开,并立刻设置 UI 到对应的视觉状态(没有动画)。
  • Insets 更新: TaskbarInsetsController 根据初始状态计算并向系统陈诉窗口 Insets。
  • 数据绑定: TaskbarViewController 开始从模子加载数据并绑定到 TaskbarView 上显示图标。
  • 事件监听与状态更新:

    • TaskbarLauncherStateController 监听 Launcher 状态变革。
    • TaskbarStashController 监听系统 UI 状态变革 (updateStateForSysuiFlags)。
    • TaskbarKeyguardController 监听锁屏状态。
    • TaskbarPinningController 监听用户 pinning 设置。
    • TaskbarStashViaTouchController 监听触摸事件。
    • 当任何影响可见性的状态发生变革时,对应的控制器会调用 TaskbarStashController.updateStateForFlag()。

  • 动画应用: TaskbarStashController.applyState() 被调用,假如计算出的收起/展开状态与当前视觉状态差别,则创建并启动动画 (mAnimator) 来平滑过渡。
  • 连续运行: Taskbar 进入运行状态,相应用户交互(点击、长按、拖拽)、系统事件和状态变革,并由 TaskbarStashController 动态调整其可见性。
核心原理:

Taskbar 的核心原理是基于状态的可见性控制动画协调


  • 状态驱动: TaskbarStashController 通过维护一组状态标志 (mState) 来会合管理所有影响 Taskbar 是否应该收起的因素。
  • 解耦: 每个子控制器负责监听和更新本身相干的状态标志,将具体逻辑与终极的可见性决议解耦。
  • 会合决议: TaskbarStashController 根据所有标志的组合,使用 mIsStashedPredicate 做出终极的收起/展开决议。
  • 动画协调: TaskbarStashController 负责创建和管理收起/展开的 AnimatorSet,该动画聚会会议同时驱动 Taskbar 背景、图标和 Handle 等多个 UI 元素的属性变革,实现协调一致的视觉过渡。
  • Insets 同步: TaskbarInsetsController 确保窗口 Insets 与 Taskbar 的状态(以及动画预期)保持一致,让应用能够正确布局。
这种设计使得 Taskbar 能够机动地相应各种复杂的系统和用户状态变革,同时保持 UI 的流通性和一致性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表