颤振-麻烦保持路线之间的焦点

时间:2018-08-26 00:08:00

标签: focus flutter

我有一个使用FocusNode的表单来直观地指示表单的哪个部分处于活动状态。一个字段将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();
        });
    }); 

2 个答案:

答案 0 :(得分:0)

您处在正确的轨道上,确实是由于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: ...
    ),);
  }
}

答案 1 :(得分:0)

非常感谢。

Iterable<OverlayEntry> createOverlayEntries() sync* {
    yield OverlayEntry(
      opaque: false,
      maintainState: true,
      builder: (content) {
        return ModalBarrier(dismissible: true);
      }
    );
    yield OverlayEntry(
      opaque: false,
      maintainState: true,
      builder: _buildContent,
    );
  }