Flutter - 无法在路线之间保持焦点
Posted
技术标签:
【中文标题】Flutter - 无法在路线之间保持焦点【英文标题】:Flutter - Trouble preserving focus between routes 【发布时间】:2019-01-31 23:34:24 【问题描述】:我有一个表单,它使用FocusNode
s 直观地指示表单的哪个部分处于活动状态。一个字段将 PopupRoute 扩展为一种弹出“键盘”。我的问题是,当我按下该字段时,键盘会弹出,但焦点的视觉效果不会出现。
来自FocusNode
的侦听器的一些调试显示它获得焦点但立即失去焦点。我想是因为新的PopupRoute
有了新的FocusScopeNode
,所以我的FocusNode
没有焦点了。
如何在另一条路线上保持该领域的焦点?我试过了:
在所有构建方法中使用FocusScope.of(context).reparentIfNeeded(focusNode)
,但没有做任何事情(我不太了解这个函数tbh)
将当前的FocusScope.of(context)
传递给我的自定义PopupRoute
以供使用。这确实有效,但弹出后,我无法再集中注意力(我猜它被丢弃了?)
代码方面,我在现场点击时调用requestFocus
,并在 initState 中添加此侦听器:
widget.focusNode.addListener(()
print(widget.focusNode);
if (widget.focusNode.hasFocus)
Navigator.of(context).push(
CustomKeyboardPopupRoute(
state: widget.state,
position: //position stuff,
focusScopeNode: FocusScope.of(context), //the second of my ideas which didn't quite work above
)
).then((_)
widget.focusNode.unfocus();
);
);
【问题讨论】:
【参考方案1】:你走在正确的轨道上,确实这是因为FocusScopeNode
。
让你的键盘路由扩展TransitionRoute
:
class CustomKeyboardPopupRoute extends TransitionRoute
@override
bool get opaque => false;
@override
Duration get transitionDuration => Duration(milliseconds: 300);
@override
Iterable<OverlayEntry> createOverlayEntries() sync*
yield OverlayEntry(
opaque: false,
maintainState: true,
builder: _buildKeyboard,
);
Widget _buildKeyboard(BuildContext context)
final positionAnimation = Tween(begin: Offset(0.0, 1.0), end: Offset.zero).animate(animation);
return SlideTransition(position: positionAnimation, child: Align(
alignment: Alignment.bottomCenter,
child: ...
),);
【讨论】:
太棒了,谢谢!通过yield
在ModalBarrier
之前_buildKeyboard
我不明白这个答案。自定义过渡如何与 FocusScope 有任何关系?抄送@卢卡斯
过渡与它没有任何关系。但是当您定义自定义路线时,您必须注意转换。这个答案的重点:如果您想将焦点保持在父路由的TextField
上,则不能将PopupRoute
用于自定义键盘。
它们以不同的方式扩展父类,其中一个区别是PopupRoute
创建了一个新的FocusScopeNode
而TransitionRoute
没有。【参考方案2】:
非常感谢。
Iterable<OverlayEntry> createOverlayEntries() sync*
yield OverlayEntry(
opaque: false,
maintainState: true,
builder: (content)
return ModalBarrier(dismissible: true);
);
yield OverlayEntry(
opaque: false,
maintainState: true,
builder: _buildContent,
);
【讨论】:
以上是关于Flutter - 无法在路线之间保持焦点的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Mobile 或 Web 应用程序之间有啥区别?
Flutter Xcode build failed 错误无法生成进程
使用 FocusScopeNode 在 TextFormFields 之间轻松移动焦点