1

我有一个CustomScrollView隐藏SliverAppBar在滚动条上的。

应用栏上有一个搜索按钮,按下该按钮时,会将 aTextField放入应用栏中。

当该字段获得焦点时,它会导致滚动视图一直滚动到顶部,并且应用栏会卡在“不安全”区域中:

滚动焦点问题

Scaffold 文档提到,当显示键盘时,脚手架的插图发生变化并重建脚手架,导致“如果焦点小部件位于可滚动容器内,它将滚动到视图中”。

这似乎是我不想要的行为。我看了但无法理解机制或如何抑制它。这样做有可能吗?

图像中视图的源代码在此处

我还注意到,这个问题在我之前使用非银色标准小部件的实现中没有发生。我怀疑这是因为应用栏不在可滚动视图中,而SliverAppBar在内部,CustomScrollView以便它可以与主体交互。

4

2 回答 2

1

编辑:此问题已由此 PR 修复,该 PR似乎首先出现在 Flutter 1.22.0 中。

这需要一些调查,但我最终找到了这种行为的机制。

TextField包裹EditableText。当后者获得焦点时,它将调用_showCaretOnScreen,其中包括对 的调用renderEditable.showOnScreen。这会冒泡并最终导致滚动行为。

如果我们提供给总是从以下位置返回的黑客,我们可以强制_showCaretOnScreen提前返回这里TextFieldScrollControllerfalsehasClients

class _HackScrollController extends ScrollController {
  // Causes early return from EditableText._showCaretOnScreen, preventing focus
  // gain from making the CustomScrollView jump to the top.
  @override
  bool get hasClients => false;
}

该行为似乎不是故意的,因此我将其报告为错误 #60422

注意事项

此解决方法可能不是很稳定。

我不知道hasClients覆盖可能会产生什么不利影响。

文档TextField说在“scrollController垂直滚动输入时”使用。在这个用例中,我们无论如何都不希望垂直滚动,因此解决方法可能不会导致任何问题。在我的简短测试中,它似乎没有导致水平(溢出)滚动问题。

于 2020-06-27T13:11:42.843 回答
0

就像文档中提到的那样,在脚手架小部件https://api.flutter.dev/flutter/material/Scaffold/resizeToAvoidBottomInset.html中尝试使用 resizeToAvoidBottomInset 参数为 false(默认为 true)

此外,我建议在脚手架之后创建 ValueListenableBuilder(作为正文中的第一个小部件),以避免重建整个脚手架和仅主体小部件

于 2020-06-25T14:33:30.813 回答