导航到另一个屏幕后,TextField 获得焦点

Posted

技术标签:

【中文标题】导航到另一个屏幕后,TextField 获得焦点【英文标题】:TextField is gaining focus after navigating to another screen 【发布时间】:2020-11-27 13:01:16 【问题描述】:

在我的项目中,我将整个 MaterialApp 包装在 GestureDetector 中,当用户使用这段代码点击屏幕时,它应该会关闭键盘

FocusScope.of(context).unfocus()

在测试了多个场景后,它都不起作用,所以我决定用错误的方式来做

FocusScope.of(context).requestFocus(FocusNode())

但现在我遇到了另一个问题。这是我的简单屏幕代码,由MaterialApproutes builder 实例化。

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget 
  @override
  _TestScreenState createState() => _TestScreenState();


class _TestScreenState extends State<TestScreen> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Column(
        children: <Widget>[
          TextFormField(),
          FlatButton(
              onPressed: () => Navigator.push(context,
                  MaterialPageRoute(builder: (context) => TestScreen())),
              child: Text('Test'))
        ],
      ),
    );
  

重现错误的步骤是:1-开始编辑TextField。 2-通过点击屏幕上的某处来取消焦点TextField。 3-点击按钮导航到另一个屏幕。结果如下:

当我试图通过按下键盘的完成按钮来解除TextField 的焦点时,不会发生这种行为。根据按下完成按钮时的源代码,TextFieldTextEditingController 上调用clearComposing。我什至尝试过,但没有运气。我该如何解决?还有其他人有更好的解决方案来处理 Flutter 中的关闭键盘吗?

这也是我的flutter doctor 结果:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.17.5, on Mac OS X 10.15.5 19F101, locale en-US)
 
[✓] android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for ios and macOS (Xcode 11.6)
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.47.3)
[✓] Connected device (2 available)

• No issues found!

【问题讨论】:

兄弟试试pub.dev/packages/keyboard_avoider 我想你没有得到这个问题。这个库正在改变滚动行为@ParthPitroda 为什么你不在 onPressed 里面做 FocusScope.of(context).unfocus() ? 它不工作,TextField 仍然是焦点 @jitsm555 您要先关闭键盘然后再进行导航吗?你的问题不清楚 【参考方案1】:

在与焦点管理相关的 GitHub 问题上搜索了很多之后,似乎没有人知道这样做的正确方法是什么。最后这行代码解决了我的问题:

WidgetsBinding.instance.focusManager.primaryFocus?.unfocus();

我不知道它的副作用,但它现在正在工作。

【讨论】:

【参考方案2】:

你在这里面临两个问题:

    flutter 中的预期行为是,当推送到新路由时,前一个路由的焦点仍然存在,这意味着当您弹回时,TextField 仍然是焦点。请参阅此flutter github 关于该主题的讨论。

    您有两个由 onTap 指针手势触发的GestureDetector。您用来解除焦点的包装器,以及用于导航到另一条路线的 FlatButton。当您点击按钮时,底层GestureRecognizer 将此事件的处理控制权交给按钮,并且包装器GestureDetector opTap() 不会被调用(这意味着未调用 unfocus)。

【讨论】:

感谢您的回答,但我认为您误解了这个问题。问题是,在取消聚焦“TextField”后,当我推动另一条路线时,键盘会弹出

以上是关于导航到另一个屏幕后,TextField 获得焦点的主要内容,如果未能解决你的问题,请参考以下文章

导航到另一个ViewController后没有获取Tabbar

TextField 获得焦点时如何滚动到 SingleChildScrollView 的底部?

单击“TextInput”对象后在 Kivy 中重新获得键盘焦点

TextField 中的 IOS8 文本在焦点上反弹

发布屏幕更改通知后如何控制哪个 UIAccessibilityElement 获得焦点?

SwiftUI 在失去焦点时运行函数 TextField