如何在 Flutter 中完全取消对 TextField 的关注,而无需稍后返回焦点

Posted

技术标签:

【中文标题】如何在 Flutter 中完全取消对 TextField 的关注,而无需稍后返回焦点【英文标题】:How to fully unfocus TextField in flutter without focus coming back later 【发布时间】:2021-01-14 09:00:10 【问题描述】:

在我的颤振应用程序中,我有一个文本字段,我希望能够通过点击一个不可交互的组件来移除焦点。这不是 Flutter 中文本字段的默认行为,因此我需要找到一种手动执行此操作的方法。按照https://flutterigniter.com/dismiss-keyboard-form-lose-focus/ 和其他各种页面的步骤,我已经让它有点工作了,其中涉及到根部的 GestureDetector 和一个看起来像这样的 onTap:

onTap: () 
  FocusScopeNode cf = FocusScope.of(context);
  if (!cf.hasPrimaryFocus && cf.focusedChild != null) 
    cf.focusedChild.unfocus();
    cf.unfocus();
  

问题是当我选择文本字段时,单击其他位置(此时焦点似乎消失),打开时间选择器,然后关闭该时间选择器,文本字段再次获得焦点。如果我通过单击键盘上的“完成”按钮来取消对文本字段的关注,那么打开/关闭时间选择器不会重新关注文本字段,所以我知道它必须是我取消关注它的方式的问题。什么是散焦的正确方法,这样焦点就不会像那样回来了?

【问题讨论】:

【参考方案1】:

将整个屏幕包裹到GestureDetector 有两种方法可以关闭键盘\

    FocusScope.of(context).requestFocus(FocusNode());
import 'package:flutter/services.dart';

SystemChannels.textInput.invokeMethod('TextInput.hide');

所以请尝试使用此代码

import 'package:flutter/services.dart';
onTap()
    SystemChannels.textInput.invokeMethod('TextInput.hide');
   

【讨论】:

我已经尝试过FocusScope.of(context).requestFocus(FocusNode());,它仍然有同样的问题,我打开时间选择器后焦点又回来了。 SystemChannels方法也没有修复它,它只是隐藏了键盘而不移除焦点,然后当我打开时间选择器时键盘又回来了。【参考方案2】:

我想通了,看来我需要在根的 GestureDetector 中使用onTap: () => FocusManager.instance.primaryFocus.unfocus()。我很确定这是解决这个特定问题的最佳方法,但我不确定它是否会导致副作用。

【讨论】:

unfocus 对我有用,但 GestureDetector 只有在没有其他任何东西可以捕捉到水龙头的情况下才会捕捉到它。所以屏幕上的任何其他按钮也必须调用 unfocus。【参考方案3】:

不需要调用unfocus 方法对我有用的是我告诉TextField 本身不要请求自己的焦点。 在文本字段本身中,我添加了:

focusNode: FocusNode(canRequestFocus: false),

我相信这是正确的处理方式。

【讨论】:

以上是关于如何在 Flutter 中完全取消对 TextField 的关注,而无需稍后返回焦点的主要内容,如果未能解决你的问题,请参考以下文章

如何创建下拉视图文本 FAQ Flutter UI

如何在 Flutter 中完全隐藏密码输入?

Flutter Firebase Cloud Messaging 如何自动关闭/取消通知?

如何从 TextField 中删除内容填充?

如何让 Flutter 应用在​​ android 导航栏后面绘制并使导航栏完全透明?

Chrome 与 Firefox 将取消对 FTP 的支持