在路由后,TextField单击重建/重新加载小部件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在路由后,TextField单击重建/重新加载小部件相关的知识,希望对你有一定的参考价值。
我有一个问题,当使用文本字段时,整个屏幕小部件重新加载。当应用程序加载此屏幕作为登录页面时,不会发生这种情况。
但是当路由从另一个页面发生到此页面并且单击文本字段时,则会发生重建。
我甚至尝试了一个简单的应用程序,这是正在复制。尝试了很多方法,但无法找到解决方案。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
class Screen1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Screen 1"), // screen title
),
body: new Center(
child: new Column(
children: <Widget>[
new RaisedButton(
onPressed: () {
button1(context);
},
child: new Text("Go to Screen 2"),
)
],
),
),
);
}
}
class Screen2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("Widget rebuilds");
return new Scaffold(
appBar: new AppBar(
title: new Text("Screen 2"),
),
body: new Center(
child: new Column(
children: <Widget>[
new Container(
height: 350.0,
child: TextFormField(
keyboardType: TextInputType.text,
style: TextStyle(fontSize: 16.0, color: Colors.black),
)),
],
),
),
);
}
}
void main() {
runApp(new MaterialApp(
home: new Screen1(),
routes: <String, WidgetBuilder>{
'/screen2': (BuildContext context) => new Screen2()
},
));
}
void button1(BuildContext context) {
print("Button 1");
Navigator.of(context).pushNamed('/screen2');
}
在这里,应用程序加载了屏幕1并单击按钮转到屏幕2将加载具有文本字段的屏幕2。单击此字段将显示键盘并单击键盘上的完成,然后再次关注文本字段将重建屏幕。这在键盘出现和消失时会一直发生。
但是,如果将Screen2设置为登录页面,则单击文本字段并执行上述相同的过程将不会重新加载窗口小部件。小部件构建只发生一次。似乎问题是从屏幕1导航Screen2的时间
runApp(new MaterialApp(
home: new Screen2(),
routes: <String, WidgetBuilder>{
'/screen2': (BuildContext context) => new Screen2()
},
));
答案
这是正常的行为,它没有问题。它实际上是在build
方法的规范内:它可以被称为任意数量的时间,你应该期望它是如此。
如果这导致问题,那么你的build
函数很可能不是纯粹的。这意味着它包含诸如http调用或类似的副作用。
这些不应该在build
方法中完成。更多细节在这里:How to deal with unwanted widget build?
关于“触发构建的因素”,有几种常见情况:
- 路由弹出/推送,用于输入/输出动画
- 屏幕调整大小,通常是由于键盘外观或方向更改
- 父窗口小部件重新创建其子项
- 小部件依赖于(
Class.of(context)
模式)更改的InheritedWidget
以上是关于在路由后,TextField单击重建/重新加载小部件的主要内容,如果未能解决你的问题,请参考以下文章
在同一导航单击上重新加载路由器组件 - 在导航单击上刷新页面