项目中经常遇到这样的场景,比如很多App都有的收藏、点赞列表等,当我们从收藏列表点击一个item项进入到详情页时,用户点击了取消收藏,那么当我们点击返回到收藏列表页时,App需要主动刷新收藏列表的数据。
在原生开发时,我们可以在收藏列表页的 onResume( ) 方法中重新请求数据并刷新列表。也可以做事件监听,不过没必要哈,事件监听比较适合那种跨页面的。
那么,Flutter 开发中,我们该如何实现该需求呢?
答案:Flutter 监听路由返回
1、使用 Navigator.push( ).then( ):在 then 的函数体内重新获取当前页面的数据并刷新列表;另外在 then 的函数体内还可以获取到被跳转页面返回时回传的参数(value值);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage()),
).then((value) => reGetData());
2、使用 RouteAware 对路由进行监听
先看看RouteAware是如何定义的?
/// An interface for objects that are aware of their current [Route].
///
/// This is used with [RouteObserver] to make a widget aware of changes to the
/// [Navigator]'s session history.
abstract class RouteAware {
/// Called when the top route has been popped off, and the current route
/// shows up.
void didPopNext() { }
/// Called when the current route has been pushed.
void didPush() { }
/// Called when the current route has been popped off.
void didPop() { }
/// Called when a new route has been pushed, and the current route is no
/// longer visible.
void didPushNext() { }
}
2.1、程序入口添加
// 用于路由返回监听
static final RouteObserver<PageRoute> routeObserver =
RouteObserver<PageRoute>();
2.2、MaterialApp 下添加
navigatorObservers: [App.routeObserver], // 注:这里可以添加多个 NavigatorObserver
2.3、所在页面添加 with RouteAware
class _CollectionPageState extends State<CollectionPage> with RouteAware {}
2.4、添加订阅和移除订阅
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 添加监听订阅
App.routeObserver.subscribe(this, ModalRoute.of(context));
}
@override
void dispose() {
// 移除监听订阅
App.routeObserver.unsubscribe(this);
super.dispose();
}
2.5、监听 RouteAware 的相关方法、按需实现所要的操作
@override
void didPush() {
// push进入当前页面时走这里
super.didPush();
onResume();
}
@override
void didPopNext() {
super.didPopNext();
// 从其他页面pop回当前页面走这里
onResume();
}
@override
void didPop() {
super.didPop();
// pop出当前页面时走这里
onPause();
}
@override
void didPushNext() {
super.didPushNext();
// 当前页面push到其他页面走这里
onPause();
}
使用步骤如上所述的 5 步,可在抽离出的 onResume( )、onPause( ) 方法中可以做一些想要的操作,来满足项目需求。
3、deactivate( ):抽象类 State 的抽象方法,当这个对象从树中移除时调用。
@override
void deactivate() {
bool isBack = ModalRoute.of(context).isCurrent;
if (isBack) {
// 限于从其他页面返回到当前页面时执行,首次进入当前页面不执行
// 注:此方法在iOS手势返回时,不执行此处
debugPrint('从其他页面返回到${widget.runtimeType}页');
} else {
// 离开当前页面或退出当前页面时执行
debugPrint('离开或退出${widget.runtimeType}页');
}
super.deactivate();
}