Flutter通过路由实现类似Android的 startActivity页面跳转.
核心类:
Route : 一个抽象的入口. 代表一个页面
Navigator : 管理Route的Widget.
页面跳转
普通路由:
跳转到下一页面
Navigator.push(context, MaterialPageRoute(builder: (context)=>TargetPage()));
返回上一页面
Navigator.pop(context);
或者
Navigator.of(context).pop();
ps:
(context)=>TargetPage(),为dart的语法.相当于(context){TargetPage();}.当方法体内只有一个语句,便可使用=>进行简写
命名路由
1.首先定义一个 routes
return MaterialApp(
initialRoute: "/",//有声明initialRoute就不用指定home了
routes: {
'/':(context)=>MainPage(),
'/second':(context)=>TargetPage()
},
);
2.跳转到下一个页面
Navigator.pushNamed(context, '/second');
3.返回上一个页面
Navigator.pop(context);
混合栈跳转
Native跳转到Flutter页面(以android为例):
这种跳转flutter是包裹在一个activity里
MainActivity:
Intent intent = new Intent(this,FlutterContainerActivity.class);
startActivity(intent);
FlutterContainerActivity:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FlutterView flutterView = Flutter.createView(this, getLifecycle(), "defaultRoute");
setContentView(flutterView);
}
Flutter跳转到Native:
flutter跳转到Native则要通过方法通道MethodChannel实现.

FlutterContainerActivity:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化flutter容器
FlutterView flutterView = Flutter.createView(this, getLifecycle(), "defaultRoute");
//创建方法通道
new MethodChannel(flutterView,"customName").setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
if (methodCall.method.equals("openNativePage")){
startActivity(new Intent(FlutterContainerActivity.this,FlutterCallActivity.class));
result.success(0);
}else if(methodCall.method.equals("closeNativePage")){
finish();
result.success(0);
}else {
result.notImplemented();
}
}
});
setContentView(flutterView);
}
Flutter:
//获取方法通道
static const platChannel = MethodChannel("customName");
//打开Native页面
void openNativePage() async {
await platChannel.invokeMethod('openNativePage');
}
//关闭Native页面
platChannel.invokeMethod('closeNativePage')),
路由传参
通过构造函数传参:
在目标函数定义一个构造方法
class TargetPage{
final String text;
const SecondRoute({Key key,this.text}) : super(key: key);
}
跳转下一页面
Navigator.push(context,MaterialPageRoute(builder:(context)=>TargetPage(text:"hello world")))
通过arguments传参:
这种方式类似android中通过intent传递数据的方式.而且这种方式是命名路由特有的.也就是pushNamed的第三个可选参数
@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
BuildContext context,
String routeName, {
'Object arguments',
})
目标界面使用ModalRoute接收传过来的数据
final data = ModalRoute.of(context).settings.arguments;
通过onGenerateRoute传参:
构建onGenerateRoute,onGenerateRoute相当于一个拦截器,截获信息然后分配给指定路由
onGenerateRoute: (settings) {
print("onGenerate");
if (settings.name == '/second') {
return MaterialPageRoute(
builder: (context) => TargetPage(
text: settings.arguments,
));
}
return MaterialPageRoute(builder: (context) => MainPage());
},
跳转到下一页面
Navigator.pushNamed(context, '/second',arguments: 'hello flutter');
ps: 只有在定义的
routes中找不到指定的路由,才会回调onGenerateRoute.
接收上一页面返回的数据:
如果需要像android中的startActivityForResult从目标页面获取数据并返回,该如何实现呢?
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
从上面我们可以看到,push其实是有返回值的,返回一个Future对象.这是一个异步结果对象,所以需要使用到async,await
void skip(BuildContext context) async{
final resultData = await Navigator.push(context, MaterialPageRoute(builder: (context)=>TargetPage()));
//打印结果
print(resultData.toString());
}
目标页面返回
Navigator.pop(context,'hi~~');