flutter - 为什么 build() 在后台堆栈中的屏幕上被多次调用?
问题描述
我创建了一个类似于Navigate to a new screen and back示例的示例项目。我在每个屏幕上的唯一TextField
区别autofocus: true
:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
home: FirstScreen(),
));
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("FirstScreen build");
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child: Text('Next screen'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
),
TextField(
decoration: InputDecoration(),
onEditingComplete: () {},
autofocus: true,
)
],
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("SecondScreen build");
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child: Text('Next screen'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ThirdScreen()),
);
},
),
TextField(
decoration: InputDecoration(),
onEditingComplete: () {},
autofocus: true,
)
],
),
);
}
}
class ThirdScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("ThirdScreen build");
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
child: Text('Next screen'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FourthScreen()),
);
},
),
TextField(
decoration: InputDecoration(),
onEditingComplete: () {},
autofocus: true,
)
],
),
);
}
}
class FourthScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("FourthScreen build");
return Scaffold(
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(),
onEditingComplete: () {},
autofocus: true,
)
],
),
);
}
}
当我导航ThirdScreen
到FourthScreen
我的日志时,如下所示:
I/flutter ( 7523): FourthScreen build
I/flutter ( 7523): SecondScreen build
I/flutter ( 7523): ThirdScreen build
I/flutter ( 7523): FourthScreen build
I/flutter ( 7523): SecondScreen build
I/flutter ( 7523): ThirdScreen build
I/flutter ( 7523): FourthScreen build
- 为什么在第一次构建 FourthScreen 之后,又调用 SecondScreen、ThirdScreen 和 FourthScreen build?
- 为什么后台的屏幕在键盘弹出时会被reguild?
- 为什么 FirstScreen 没有被重建?
解决方案
我遇到了同样的问题,我使用以下方法解决了这个问题。
- 使用提供者获取当前页面。
- 创建一个String类型的变量route(route为变量名)
- 在每个屏幕上调用提供商并分配该屏幕名称。
- 在屏幕上或菜单抽屉上或您正在导航的任何地方呼叫提供商。
提供者类代码
class RouteProvider with ChangeNotifier {
String _route = "initial";
String get route => _route;
set route(String data) {
this._route = data;
notifyListeners();
}
}
在 build() 中将 rout/screen 名称分配给提供者
final route = context.watch<RouteProvider>().route = "OffersView";
在内部构建的消费者屏幕上
final route = context.watch<RouteProvider>().route;
if (route != "OffersView") {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (Context) => OffersPage()),
(route) => false);
}
推荐阅读
- xcode - NSComboBox 使用 NSValueTransformer 自动完成
- python - Python 3.X:如何调用类的函数来检查输入字符串的特征?
- python - 将深度嵌套的字典转换为熊猫数据框?
- android - 如何保持我的 Android VideoView 的纵横比仅与其高度成比例?
- r - 如何从 R 包中的函数生成 html / pdf 报告
- azure - 使用 helm 从 ACR 中拉取容器
- powershell - 如何处理使用powershell比较现有文件的if语句?
- azure-storage - 每个文件单独的 SharedAccessFilePolicy 可以吗?
- pytorch - 在 torch.sparse_coo_tensor(indices, values, size=None, dtype=None, device=None, requires_grad=False) 的输出中,nnz 是什么意思?
- javascript - 为什么我不能将 `push` 函数分配给变量?