Flutter 的 Navigation 2.0 没有更新 UI
Flutter's Navigation 2.0 doesn't update the UI
我正在尝试了解如何使用 Flutter 的声明式导航系统。我想创建一个简单的应用程序,它将无限地添加/删除到堆栈的路由。比如,“Screen N”有两个按钮:首先将它从堆栈中弹出,然后将“Screen N+1”添加到堆栈中。所以,我制作了一个有状态的小部件来保存导航器状态 (pages
):
class _MyAppState extends State<MyApp> {
final List<Page> _pages = <Page>[];
@override
void initState() {
super.initState();
_dive(0);
}
@override
Widget build(BuildContext context) {
print(_pages);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Navigator(
pages: _pages,
onPopPage: (route, result) {
route.didPop(result);
return true;
},
),
);
}
void _arise() {
setState(() {
print("Arise!");
_pages.removeLast();
});
}
void _dive(int value) {
setState(() {
print("Dive!");
_pages.add(
MaterialPage(
key: ValueKey(value),
child: DiveRoute(
value,
_arise,
_dive,
),
),
);
});
}
}
这是一个“第 N 屏”小部件:
class DiveRoute extends StatelessWidget {
final int _value;
final void Function() _arise;
final void Function(int) _dive;
const DiveRoute(
this._value,
this._arise,
this._dive, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dive"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("$_value"),
ElevatedButton(
onPressed: () => _arise(),
child: Text("Up"),
),
ElevatedButton(
onPressed: () => _dive(_value + 1),
child: Text("Down"),
),
],
),
),
);
}
}
该应用程序正确绘制了第一个屏幕 (0),但单击按钮不会更新 UI,尽管 prints
在控制台中可见并且我看到列表页面增长和收缩。
我不确定为什么,但是通过更换
解决了这个问题
pages: _pages,
和
pages: _pages.toList(),
或
pages: [..._pages],
尽管两种变体都可以正确编译。
他们使用 !=
来比较 pages
变量(navigator.dart):
if (oldWidget.pages != widget.pages && !restorePending) {
因此每次更新 pages
变量时都需要提供一个新实例。
我正在尝试了解如何使用 Flutter 的声明式导航系统。我想创建一个简单的应用程序,它将无限地添加/删除到堆栈的路由。比如,“Screen N”有两个按钮:首先将它从堆栈中弹出,然后将“Screen N+1”添加到堆栈中。所以,我制作了一个有状态的小部件来保存导航器状态 (pages
):
class _MyAppState extends State<MyApp> {
final List<Page> _pages = <Page>[];
@override
void initState() {
super.initState();
_dive(0);
}
@override
Widget build(BuildContext context) {
print(_pages);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Navigator(
pages: _pages,
onPopPage: (route, result) {
route.didPop(result);
return true;
},
),
);
}
void _arise() {
setState(() {
print("Arise!");
_pages.removeLast();
});
}
void _dive(int value) {
setState(() {
print("Dive!");
_pages.add(
MaterialPage(
key: ValueKey(value),
child: DiveRoute(
value,
_arise,
_dive,
),
),
);
});
}
}
这是一个“第 N 屏”小部件:
class DiveRoute extends StatelessWidget {
final int _value;
final void Function() _arise;
final void Function(int) _dive;
const DiveRoute(
this._value,
this._arise,
this._dive, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dive"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("$_value"),
ElevatedButton(
onPressed: () => _arise(),
child: Text("Up"),
),
ElevatedButton(
onPressed: () => _dive(_value + 1),
child: Text("Down"),
),
],
),
),
);
}
}
该应用程序正确绘制了第一个屏幕 (0),但单击按钮不会更新 UI,尽管 prints
在控制台中可见并且我看到列表页面增长和收缩。
我不确定为什么,但是通过更换
解决了这个问题pages: _pages,
和
pages: _pages.toList(),
或
pages: [..._pages],
尽管两种变体都可以正确编译。
他们使用 !=
来比较 pages
变量(navigator.dart):
if (oldWidget.pages != widget.pages && !restorePending) {
因此每次更新 pages
变量时都需要提供一个新实例。