我有一个 CustomScrollView
和一个在滚动时隐藏的 SliverAppBar
。
应用栏上有一个搜索按钮,按下该按钮会将 TextField
放入应用栏。
当字段获得焦点时,它会导致 ScrollView 一直滚动到顶部,并且应用栏卡在“不安全”区域:
Scaffold docs提到当显示键盘时,脚手架的插图会发生变化并且脚手架会被重建,从而导致“如果聚焦的小部件位于可滚动容器内,则该小部件将滚动到 View 中”。
这似乎是我不想要的行为。我看了看,但不明白其中的机制或如何抑制它。这样做可能吗?
图中 View 的源代码是here .
我还注意到,这个问题在我之前使用非条子标准小部件的实现中没有发生。我怀疑这是因为应用栏不在可 ScrollView 中,而 SliverAppBar
位于 CustomScrollView
内部,以便它可以与主体交互。
最佳答案
编辑:此问题已由 this PR 修复它似乎首先出现在 Flutter 1.22.0 中。
我进行了一些调查,但最终找到了这种行为的机制。
TextField
包装 EditableText
。当后者获得焦点时,它将调用 _showCaretOnScreen
,其中包括a call to renderEditable.showOnScreen
。这会冒泡并最终导致滚动行为。
我们可以强制_showCaretOnScreen
提前返回here如果我们向 TextField
提供一个被黑的 ScrollController
,它总是从 hasClients
返回 false
:
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;
}
该行为似乎不是故意的,因此我将其报告为 bug #60422 .
注意事项
此解决方法可能不是很稳定。
我不知道 hasClients
覆盖可能会产生什么不利影响。
docs for TextField
说 scrollController
用于“垂直滚动输入时”。在此用例中,我们无论如何都不希望垂直滚动,因此解决方法可能不会导致任何问题。在我的简短测试中,它似乎没有导致水平(溢出)滚动问题。
关于flutter - 如何抑制 Flutter 中的滚动到 View 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62576622/