flutter - Navigator.push 将在 Navigator.push 之后关注目标页面上的文本字段时再次调用
问题描述
出现以下现象。
- 从 过渡
FirstPage
到NextPage
byNavigation.push
。 - 选择一个
TextField
。NextPage
- 1 再次被调用。
- 用键盘搞定。
- 1 再次被调用。
下面是源码。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("sample"),
),
body: RaisedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
print("Before call NextPage()");
return NextPage();
}),
);
},
child: Text("next page"),
),
);
}
}
class NextPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("next page"),
),
body: TextField(),
);
}
}
下面是在点击 TextField 和 DONE 键盘时打印日志的动画 gif。
为什么会这样?(错误?)
我该如何解决?
解决方案
如您所见,即使该日志被多次调用,您也只会看到第一个的转换,或者换句话说,您正在获得所需的效果。发生这种情况是有原因的。让我们分解一下:
使用Flutter,builders
可以多次调用,多种原因,并且应该是幂等的(不影响逻辑业务);
话虽如此,当您导航到第二个屏幕时,您正在构建一个Stateless WidgetTextFormField
`的子级,它应该是不可变的。这意味着它的最终值(如果需要)应该在构造函数中传递,并且每次状态更改(例如字段的默认文本)都将需要更改,从而通过触发构建器来重建视图;
因此,例如,如果您改用Stateful Widget,则可能不会调用您的构建器,而只会调用build
其State的方法。
您可以在此处的类似已关闭问题中找到有关此问题的讨论
推荐阅读
- firebase - firebase 实时数据库:TypeError:无法将未定义或 null 转换为对象
- javascript - 如何在 javascript 中将 jQuery 的值分配给 PHP SESSION
- c# - 为什么要创建父类的类型来存储子类的对象?
- python - 我们可以将 fastText 与 SVM 一起集成吗?
- javascript - 在nodejs中通过带有构造函数的模块公开多个对象
- go - 如何在 Go 语言的模板中获取嵌入变量
- java - 本机库 D:\jdk 1.8.0 181\jre1.8.0_181\bin\glass.dll 已在另一个类加载器中加载
- actions-on-google - 启用智能显示器
- docker - 无法从 Jenkins 管道连接远程 docker 主机 api
- java - Android:将 CheckBox 状态存储在不同日期的 CheckList 中