Flutter:使用popUntil导航到页面时如何更新页面
Posted
技术标签:
【中文标题】Flutter:使用popUntil导航到页面时如何更新页面【英文标题】:Flutter: How to update a page when using popUntil to navigate to it 【发布时间】:2020-09-30 06:49:45 【问题描述】:我有一个应用程序,它有一个基本页面,其中包含许多不同对象的 ListTile,这些对象基于全局主列表填充。如果用户单击其中一个 ListTile 磁贴,它将导航到一个新页面(第二页),其中包含有关该对象的特定信息。我还有左右按钮,允许用户导航全局列表而无需跳回主页。如果用户看到他们喜欢的对象,他们可以将其添加到他们的“已保存”列表中,这会将其从潜在对象的全局列表中删除,并将其添加到已保存列表中。在他们添加对象后,我使用 popUntil 返回到主页,但是“保存的”对象没有被删除。根据阅读下面的答案,我了解到我的问题可能与颤振无法识别列表中的更改因此不会重绘页面这一事实有关。我看到了一个关于添加多余计数器的建议,但无法弄清楚如何将它集成到我自己的 popUntil 实现中,因为这个问题稍微简单一些并且不使用 popUntil。当我 popUntil 我到达那里时,我应该怎么做才能强制应用重绘主页?
Force Flutter navigator to reload state when popping
这是第一页(假设我在到达这里之前将其命名为“主”路由。)
final List<Object> _potentials = List<Object>();
final List<Object> _saved = List<Object>();
class MainPage extends StatefulWidget
@override
_MainPageState createState() => _MainPageState();
class _MainPageState extends State<MainPage>
@override
build (BuildContext context)
final tiles = _potentials.map(
(Object thing)
return ListTile(
leading: Icon(Icons.person),
title: Text(thing.name),
onTap: ()
selectedThing = thing;
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondPage()
)
);
,
);
,
);
... //there is more stuff here building out the tile views
这是 popUntil 所在的第二页
class SecondPage extends StatefulWidget
@override
_SecondPageState createState() => _SecondPageState();
class _SecondPageState extends State<SecondPage>
@override
build (BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(selectedThing.name),
leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: ()
Navigator.popUntil(context, ModalRoute.withName('Main'));
),
actions: [
IconButton(icon: Icon(Icons.person_add), onPressed: ()
_saved.add(selectedThing);
_potentials.remove(selectedThing);
Navigator.popUntil(context, ModalRoute.withName('Main'));
),
],
),
... //more stuff here that isn't important
// (including the left and right navigation buttons which take you to a new second page and update selectedThing)
【问题讨论】:
【参考方案1】:我不完全了解您的状态管理或您将所有变量保存在哪里,但您可以做的一件事是检查 _potentials 或 _saved 是否更改。 Navigator.pop 返回一个 Future,即使 Navigator.popUntil 是无效的,你也可以通过一些异步来利用它来发挥你的优势
onTap: () async
selectedThing = thing;
final int length = _saved.length; //save a reference of the length of your list _saved
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SecondPage()
); // await here until the popUntil from the second screen
/*
After the popUntil of the secondPage returns to this page it will run this next line (because the aync await future),
so if the user tap on the back arrow the list didn't change and the length are the same,
if he taps on the person_add Icon, you remove that object from _potentials and add it to _saved,
so the lenght are different and it runs setState, forcing to rebuild MainPage.
this.mounted is just for safety to make sure the MainPage is mounted in the tree and wasn't popped by mystake,
it's unsafe to call setState without being sure the state object is there
*/
if(length != _saved.length && this.mounted) setState(());
,
还有其他方法可以确保列表发生变化,使用import 'package:collection/collection.dart';
和DeepCollectionEquality.unordered().equals(list1, list2);
来检查列表是否相同
【讨论】:
感谢您的回复,我还不清楚一件事,并且在我实施时对我不起作用。 Navigator.push 在新设置的 onTap 中添加了异步功能在哪里?您现在拥有的代码没有导航到第二页。 抱歉忘记改回来了,我是用pushNamed来测试的,刚改回你的push,我更新了答案 太棒了,现在效果很好!非常感谢您的帮助以上是关于Flutter:使用popUntil导航到页面时如何更新页面的主要内容,如果未能解决你的问题,请参考以下文章
断言失败:在 Flutter 中使用 Navigator.popUntil() 时 !_debugLocked 不正确