前言
我們通常有這樣一個需求:點選修改使用者資訊需要跳轉頁面,修改完成以後返回之前的頁面我們需要重新獲取新的資料重新整理修改後的資料。於是就找方法去實現,目前我用過的就是以下三種方法。
程式碼地址
Navigator.of(context).pushNamed().then()
優點
- 可以在返回頁面的時候在
pop
中傳入引數Navigator.pop(context, '資料傳參')
,.then(value => print(value))
,value的值就是資料傳參
。(使用手勢返回接收不到引數值列印為null
) .then
方法中可以監聽到手勢返回和Navigator.pop
返回。
缺點
- 頁面上跳轉不同頁面較多需要在每一個
then
方法中處理,哪怕寫成公共方法也需要都加一次。
用法
// 路由跳轉監聽返回該頁面
Navigator.of(context).pushNamed(
'/newView',
arguments: NewView(
content: '網路搜尋結果漢語- 維基百科,自由的百科全書',
),
).then((value) => print(value));
// 返回之前的頁面帶上引數
Navigator.pop(context, '資料傳參');
複製程式碼
效果展示
deactivate
優點
- 返回到該頁面的時候我們只需要在一個地方發請求獲取新的資料,不需要單獨加在每一個頁面跳轉的
then
方法內,理論上可以滿足我們的需求。
缺點
- 雖然
deactivate
會被觸發,但是進入頁面或者返回頁面都會被觸發,於是使用ModalRoute.of(context).isCurrent
判斷是否是當前頁面,為true
就發請求獲取新的頁面。當使用手勢返回的時一直是false
,就會導致不發請求重新整理資料。 - 不能直接獲取到引數
用法
void deactivate() {
super.deactivate();
var bool = ModalRoute.of(context).isCurrent;
if (bool) {
// 監聽到頁面返回,發請求重新整理頁面操作
print('返回NewView頁面');
}
}
複製程式碼
效果展示
didPopNext
優點
didPopNext
可以彌補手勢返回不觸發的問題,我們也不需要去寫額外的判斷。
缺點
- 不能直接獲取到引數
用法
// 在MaterialApp中監聽
class DynamicTheme extends StatefulWidget {
const DynamicTheme();
static final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
@override
_DynamicThemeState createState() => _DynamicThemeState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dynamic Theme',
theme: lightTheme.copyWith(platform: _options.platform),
darkTheme: darkTheme.copyWith(platform: _options.platform),
themeMode: _options.themeMode,
...
navigatorObservers: [DynamicTheme.routeObserver],
...
routes: _buildRoutes(),
);
}
// 頁面使用
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class NewView extends StatefulWidget {
final String content;
const NewView({
this.content,
});
static const String routeName = '/newView';
@override
_NewViewState createState() => _NewViewState();
}
class _NewViewState extends State<NewView> with RouteAware {
@override
void didChangeDependencies() {
super.didChangeDependencies();
DynamicTheme.routeObserver.subscribe(this, ModalRoute.of(context));
}
@override
void didPopNext() {
// Covering route was popped off the navigator.
print('返回NewView');
}
@override
void didPush() {
// Route was pushed onto navigator and is now topmost route.
print('進入NewView');
}
@override
void dispose() {
DynamicTheme.routeObserver.unsubscribe(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
// final NewView param = ModalRoute.of(context).settings.arguments;
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
leading: CupertinoButton(
padding: EdgeInsets.zero,
child: Text('返回'),
onPressed: () {
// The demo is on the root navigator.
// Navigator.of(context, rootNavigator: true).maybePop();
Navigator.pop(context, '資料傳參');
},
),
),
child: Material(
child: ScrollConfiguration(
behavior: CustomBehavior(),
child: ListView.builder(
primary: true,
itemCount: 60,
itemBuilder: (BuildContext context, int index) {
return Ink(
child: InkWell(
splashColor: Colors.transparent,
onTap: () => Navigator.of(context).pushNamed(
Detail.routeName,
arguments: Detail(value: '引數'),
),
child: Container(
height: 44.0,
width: MediaQuery.of(context).size.width,
child: Center(child: Text('Data-$index')),
),
),
);
},
),
),
),
);
}
}
複製程式碼
效果展示
總結
需要監聽頁面返回獲取新的資料只有一個跳轉使用then
方法監聽就可以,如果跳轉比較多返回以後都需要重新整理資料建議使用didPopNext
。