【问题标题】:Request TextField focus in initState在 initState 中请求 TextField 焦点
【发布时间】:2019-11-05 21:31:58
【问题描述】:

我有一个带有 UID 和 PWD 文本字段的登录页面。 UID,一旦提供,就会存储在共享首选项中。因此,每当显示登录屏幕时,焦点可能在 UID 文本字段(如果未提供/存储 UID)或 PWD 文本字段(如果显示或提供并自动填充 UID)。

我遇到的问题是我正在尝试使用以下方法将焦点设置到正确的 TextField:

FocusScope.of(context).requestFocus(_uidFocusNode)
FocusScope.of(context).requestFocus(_pwdFocusNode);

其中 _uidFocusNode 和 _pwdFocusNode 被定义为 FocusNodes 并通过 focusNode 属性附加到适当的 TextFields。

现在,我无法在 initState 中使用上述语句设置焦点,因为 Widget 尚未构建。但是当我在构建方法中设置它时,它会导致重建并且焦点字段一直在闪烁。有没有办法在根据逻辑构建 Widget 时设置焦点?请注意,自动对焦无法按预期工作 - 我需要将光标放在字段中。

【问题讨论】:

  • 请问您说的是 iOS/Android 应用程序还是 Web 应用程序?这是完全不同的,因为在撰写本文时自动对焦还没有在网络上工作 (github.com/flutter/flutter/issues/58498)

标签: flutter dart


【解决方案1】:

当然!您可以使用 SchedulerBinding.addPostFrameCallback 安排在构建完成后调用的函数。
你可以简单地在你的initState中使用它:

@override
void initState() {
  super.initState();

  SchedulerBinding.instance.addPostFrameCallback((Duration _) {
    FocusScope.of(context).requestFocus(condition ? _pwdFocusNode : _uidFocusNode);
  });
}

确保在文件开头添加import 'package:flutter/scheduler.dart';

【讨论】:

  • @creativecreatormaybenot,这是完美的。按照您的建议,我使用 Google addPostFrameCallback 找到了这篇精彩的文章,该文章不仅解释了原因,而且还稍微纠正了您的答案以使用 WidgetsBinding.instance.addPostFrameCallback。不过还是谢谢你。
  • @lgor 很高兴你喜欢我的回答。但是,您误解了有关WidgetsBinding 的部分,因为这无关紧要。 SchedulerBinding.addPostFrameCallbackWidgetsBinding.instance.addPostFrameCallback 完全相同因为 WidgetsBinding 继承来自 SchedulerBinding 的方法。
  • 你是对的,但我不能调用SchedulerBinding.addPostFrameCallback,因为它不是静态函数,我不知道如何在initState() 中获取函数addPostFrameCallback()
  • @Igor 对不起。您需要使用SchedulerBinding.instance 访问实例。请参阅答案中的代码 sn-p。
猜你喜欢
  • 2012-06-05
  • 2011-12-26
  • 1970-01-01
  • 2020-05-27
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多