Keyboard 如何检测在颤振中选择文本字段的时间?

Keyboard 如何检测在颤振中选择文本字段的时间?,keyboard,textfield,flutter,Keyboard,Textfield,Flutter,我有一个颤振文本字段,当该字段被选中时,它会被软键盘覆盖。当显示键盘时,我需要向上滚动该字段并将其移开。这是一个非常常见的问题,本文给出了一个解决方案 我想我已经找到了ScrollController部分,但是如何检测何时选择了文本字段?似乎没有任何事件方法(例如onFocus()、onSelected()、onTap()等) 我尝试将文本字段包装在手势检测器中,但这也不起作用——显然事件从未被捕获 new GestureDetector( child: new TextField(

我有一个颤振文本字段,当该字段被选中时,它会被软键盘覆盖。当显示键盘时,我需要向上滚动该字段并将其移开。这是一个非常常见的问题,本文给出了一个解决方案

我想我已经找到了ScrollController部分,但是如何检测何时选择了文本字段?似乎没有任何事件方法(例如onFocus()、onSelected()、onTap()等)

我尝试将文本字段包装在手势检测器中,但这也不起作用——显然事件从未被捕获

new GestureDetector(
  child: new TextField(
    decoration: const InputDecoration(labelText: 'City'),
  ),
  onTap: () => print('Text Selected'),
),

这是一个基本要求,我知道一定有一个简单的解决方案。

我想您正在寻找

要收听焦点更改,您可以向
FocusNode
添加列表,并将
FocusNode
指定为
TextField

例如:

class TextFieldFocus extends StatefulWidget {
  @override
  _TextFieldFocusState createState() => new _TextFieldFocusState();
}

class _TextFieldFocusState extends State<TextFieldFocus> {
  FocusNode _focus = new FocusNode();

  TextEditingController _controller = new TextEditingController();

  @override
  void initState() {
    super.initState();
    _focus.addListener(_onFocusChange);
  }

  void _onFocusChange(){
    debugPrint("Focus: "+_focus.hasFocus.toString());
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.white,
      child: new TextField(
        focusNode: _focus,
      ),
    );
  }
}
类TextFieldFocus扩展StatefulWidget{
@凌驾
_TextFieldFocusState createState()=>新建_TextFieldFocusState();
}
类_TextFieldFocusState扩展状态{
FocusNode_focus=新的FocusNode();
TextEditingController _controller=新的TextEditingController();
@凌驾
void initState(){
super.initState();
_focus.addListener(_onFocusChange);
}
void _onFocusChange(){
debugPrint(“焦点:”+_Focus.hasFocus.toString());
}
@凌驾
小部件构建(构建上下文){
退回新货柜(
颜色:颜色,白色,
孩子:新文本字段(
focusNode:_focus,
),
);
}
}
gist表示如何确保聚焦节点在ui上可见


希望有帮助

最简单的解决方案是在TextField上添加onTap方法

TextField(
  onTap: () {
    print('Editing stated $widget');
  },
)

要获得焦点事件的通知,您可以通过使用实用程序类
FocusScope
focus
,避免手动管理小部件的状态

从文档()中:

请参阅Focus和FocusScope小部件,它们是分别管理自己的FocusNodes和FocusScope节点的实用程序小部件。如果不合适,可以直接管理焦点节点

下面是一个简单的例子:

FocusScope(
  child: Focus(
    onFocusChange: (focus) => print("focus: $focus"),
    child: TextField(
      decoration: const InputDecoration(labelText: 'City'),
    )
  )
)

只需使用
TextField
onTap
功能即可

TextField(
onTap:(){
//你的密码。
},
);

如果您的文本字段需要出于某种目的(如我的目的)禁用,还有另一种方法。在这种情况下,您可以像这样用
InkWell
包装文本字段

InkWell(
  onTap: () {
    print('clicked');
  },
  child: TextField(
    enabled: false,
  ),
);

非常感谢你的回答。我没有尝试使用您在要点中提供的更健壮的解决方案,但是下面的简单解决方案似乎在我的测试用例中起作用。我对这个解决方案有一个问题,因为我展示了一个聚焦文本字段的覆盖图。显示覆盖像一个符咒,但一旦覆盖关闭,文本字段将再次自动聚焦,覆盖将再次弹出,然后在同一聚焦节点上显示对话框“仅调用方法”。仅当您不希望返回时对textfield进行聚焦时才执行此操作。还应在有状态小部件的dispose()中清除聚焦节点。请参见上的示例。不要忘记在dispose()中处理它;文本字段还可以通过其他方式获得焦点,例如,如果它是页面上的第一个
TextField
,未来的Flutter版本将支持在字段之间切换。Saved me!非常感谢。回答得很好,谢谢。但我确实明白,如果我使用node.nextFocus()将焦点提前到下一个文本字段,那么我就无法访问下一个字段的控制器来设置选择,就像我使用onTap()解决方案那样。简明扼要,回答得很好。谢谢对我来说,这个答案比公认的答案更有效,因为只有在点击子部件“TextField”输入文本时才会调用回调。对于ACCPEPT答案中的“addListener”方法,情况并非如此。一些父窗口小部件在点击时也会触发回调。我不太明白为什么..在android上,如果在文本字段中按下系统backbutton,[onFocusChange]将不会被触发。