如何正确使用Flutter中Navigator的pages属性?修改后返回异常怎么解决
问题原因
你对pages参数的核心理解是正确的:它确实代表页面栈,列表顺序按「栈底到栈顶」排列,列表最后一个元素是当前展示给用户的栈顶页面,用户触发返回操作时会弹出栈顶页面,下层页面自动变为激活状态。你遇到的异常表现是由声明式路由的特性和你当前逻辑的冲突导致的,具体有两点:
- 你把
RandomScreen1加在pages列表的最开头,它本身是栈底页面,默认展示的栈顶页面仍然是图书列表页,这部分和你的预期一致。 - Navigator 2.0是完全声明式的路由体系,Navigator自身的弹出行为不会修改你传入的
pages列表,所有栈的变化都必须通过修改状态变量,再重新构建新的pages列表来映射状态。你当前的onPopPage逻辑中,弹出栈顶的图书列表页后立刻调用了notifyListeners()触发重绘,而重绘时传入的pages列表仍然是[RandomScreen1, 图书列表页],等于刚弹出的图书列表页又被你重新塞回了栈顶,所以才会出现RandomScreen1闪现一秒后又回到图书列表页的问题。
修复方案
你需要新增状态变量控制图书列表页的展示权限,修改后的完整逻辑如下:
- 首先在
BookRouterDelegate中新增状态变量:
// 新增状态控制图书列表页是否展示 bool _showBooksList = true;
- 修改
build方法中的pages列表逻辑:
@override Widget build(BuildContext context) { return Navigator( key: navigatorKey, pages: [ MaterialPage( key: ValueKey('RandomScreen1Page'), child: RandomScreen1(), ), // 仅当状态变量为true时才加入图书列表页 if (_showBooksList) MaterialPage( key: ValueKey('BooksListPage'), child: BooksListScreen( books: books, onTapped: _handleBookTapped, ), ), if (show404) MaterialPage(key: ValueKey('UnknownPage'), child: UnknownScreen()) else if (_selectedBook != null) BookDetailsPage(book: _selectedBook!) ], onPopPage: (route, result) { print("onpoproute ${route} ${result} "); if (!route.didPop(result)) { print("route did not pop"); return false; } // 按层级处理弹出逻辑:先处理详情页弹出 if (_selectedBook != null) { _selectedBook = null; } // 再处理图书列表页弹出 else if (_showBooksList) { _showBooksList = false; } show404 = false; notifyListeners(); return true; }, ); }
修改完成后,在图书列表页按下返回键就会正常展示RandomScreen1页面。
内容的提问来源于stack exchange,提问作者Priyshrm
相关产品推荐
相关产品推荐

