Skip to content

关于焦点控制的讨论与计划 #300

@Daydreamer-riri

Description

@Daydreamer-riri

Description of the feature / 需求描述

Hi @GhostenEditor,最近我在研究 Flutter 中的焦点控制。发现 Flutter 默认只提供基于几何方向的简单焦点移动,而且在实际使用中,焦点落点有时并不符合预期。

在 TV 端应用的实际体验中(基于我的个人经验),大多数应用会在某个逻辑分区内记住“离开时的最后一个焦点元素”,当用户回到该区域时,焦点会自动恢复到该元素上。这种行为更符合直觉,也能避免由于列表滚动偏移而导致的意外情况。例如我提供的视频中,第 8 秒时焦点元素甚至没有出现在视口内;按预期,回到那一行时应当聚焦在我离开时所在的元素。

我体验过的其他应用(如 Jellyfin 官方客户端、网易爆米花,以及爱优腾等客户端)基本都遵循这一规则(可见我提供的视频)。因此我在想,这是否是 Flutter 在焦点控制能力上相较于 Android 原生方案的一个不足?我也希望我们能在这方面做一些改进。

Solution / 解决方案

#282 中,我尝试使用 FocusScope 来解决该问题。

方案一:FocusScope(当前尝试方案)

  • 优势:能够自动记忆并恢复内部最后的聚焦元素。
  • 痛点:Scope 之间无法自然跨越焦点,我们需要监听 KeyEvent 来手动处理 Scope 边缘的跳跃逻辑,这会增加代码复杂度,并可能引入难以预料的边界情况(例如动态插入的组件无法触达)。并且目前我还不确定在 Scope 边缘向一个未被 Scope 包裹的元素跳跃可以怎么跳,还有待研究。

方案二:社区库 [fluttercandies/dpad](https://github.com/fluttercandies/dpad)

  • 我初步调研发现该库专门优化了 Flutter 的导航与焦点逻辑,似乎是通过手动记忆焦点元素来规避 Scope 的隔离问题。
  • 现状:目前我对该库的使用方式和效果尚不确定。鉴于其需要替换最基本的Focus Widget,这可能引入的改动很大。相比较, FocusScope 方案我已经成功在章节列表页落地,不会引入太大的改动。

@GhostenEditor > 这两个方案你怎么看?如果你觉得 dpad 值得尝试,我会去尝试下调研并评估效果。

Focus / 关注点

https://photos.app.goo.gl/stZdLK254u1tE9mD9

(另外我发现 flutter 有状态的组件声明以及状态管理实在是太脱裤子放屁了…… 如果有 flutter_hooks 会好很多 (只是个人观点,如果作者不喜欢不需要理会我这句话

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions