Flutter 页面跳转及传参总结
一、Flutter 内部页面跳转与传参
Flutter 内部页面跳转主要通过 Navigator 组件实现,参数传递可通过构造函数、路由参数或状态管理工具(如 Provider、GetX 等)。
- 基础跳转方式(无命名路由)
使用 Navigator.push() 配合 MaterialPageRoute 直接跳转,通过目标页面构造函数传参。
示例:
// 目标页面(SecondPage.dart)
class SecondPage extends StatelessWidget {final String message; // 接收参数final int count;// 构造函数接收参数const SecondPage({super.key, required this.message, required this.count}); Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("第二页")),body: Center(child: Text("接收参数:$message, $count"),),);}
}// 跳转逻辑(FirstPage.dart)
ElevatedButton(onPressed: () {// 跳转并传参Navigator.push(context,MaterialPageRoute(builder: (context) => const SecondPage(message: "Hello from FirstPage",count: 100,),),);},child: const Text("跳转到第二页"),
)
- 命名路由跳转
在 MaterialApp 中定义 routes 路由表,通过 Navigator.pushNamed() 跳转,参数通过 arguments 传递。
示例:
// 1. 定义路由表(main.dart)
MaterialApp(routes: {'/second': (context) => const SecondPage(), // 注册命名路由},
);// 2. 跳转并传参(FirstPage.dart)
Navigator.pushNamed(context,'/second',arguments: { // 通过 arguments 传递参数(支持任意类型,通常用 Map)"message": "Hello from Named Route","count": 200,},
);// 3. 目标页面接收参数(SecondPage.dart)
class SecondPage extends StatelessWidget {const SecondPage({super.key}); Widget build(BuildContext context) {// 获取路由参数final Map<String, dynamic> args = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;return Scaffold(appBar: AppBar(title: const Text("第二页")),body: Center(child: Text("命名路由参数:${args['message']}, ${args['count']}"),),);}
}
- 返回数据给上一页
通过 Navigator.pop(context, result) 将数据返回给上一页,上一页通过 async/await 接收。
示例:
// 第二页返回数据
ElevatedButton(onPressed: () {Navigator.pop(context, "这是返回给第一页的数据"); // 返回数据},child: const Text("返回并传数据"),
);// 第一页接收返回数据
onPressed: () async {final result = await Navigator.push(context,MaterialPageRoute(builder: (context) => const SecondPage()),);// 处理返回数据if (result != null) {print("接收返回数据:$result");}
},
二、Android 与 Flutter 跨平台页面跳转及传参
当原生 Android 与 Flutter 混合开发时,需通过 MethodChannel 实现跨平台通信,完成页面跳转和参数传递。
- Flutter 跳转到 Android 原生页面
步骤:
Flutter 侧:通过 MethodChannel 发送跳转指令及参数;
Android 侧:监听 MethodChannel 回调,解析参数并启动原生 Activity/Fragment。
示例代码:
// Flutter 侧(发送跳转指令)
class FlutterToAndroid {static const platform = MethodChannel('com.example/navigation');static Future<void> jumpToAndroidPage() async {try {// 传递参数(Map 格式,支持基本类型)final result = await platform.invokeMethod('jumpToAndroid', {'pageName': 'DetailActivity','data': {'id': 1, 'name': 'Flutter传递的数据'}},);print("Android 返回结果:$result");} on PlatformException catch (e) {print("跳转失败:${e.message}");}}
}
// Android 侧(接收跳转指令,MainActivity.kt)
class MainActivity : FlutterActivity() {private val CHANNEL = "com.example/navigation"override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->if (call.method == "jumpToAndroid") {// 解析 Flutter 传递的参数val pageName = call.argument<String>("pageName")val data = call.argument<Map<String, Any>>("data")// 启动原生 Activityval intent = Intent(this, DetailActivity::class.java).apply {putExtra("data", data as Serializable) // 参数放入 Intent}startActivity(intent)result.success("Android 页面已打开")} else {result.notImplemented()}}}
}
- Android 原生跳转到 Flutter 页面
步骤:
Android 侧:通过 MethodChannel 向 Flutter 发送跳转指令及参数;
Flutter 侧:监听 MethodChannel 回调,解析参数并通过 Navigator 跳转内部页面。
示例代码:
// Android 侧(发送跳转指令,MainActivity.kt)
fun jumpToFlutterPage() {val flutterEngine = FlutterEngine(this)flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())// 发送参数到 FlutterMethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).invokeMethod("jumpToFlutter",mapOf("route" to "/flutterDetail","params" to mapOf("androidData" to "原生传递的数据", "count" to 99)),object : MethodChannel.Result {override fun success(result: Any?) {Log.d("Android", "Flutter 跳转结果:$result")}override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {}override fun notImplemented() {}})// 显示 Flutter 页面(通过 FlutterFragment 或 FlutterActivity)supportFragmentManager.beginTransaction().replace(R.id.flutter_container, FlutterFragment.withEngine(flutterEngine).build()).commit()
}
// Flutter 侧(接收跳转指令,main.dart)
class AndroidToFlutter {static const platform = MethodChannel('com.example/navigation');static void init() {platform.setMethodCallHandler((call) async {if (call.method == "jumpToFlutter") {// 解析 Android 传递的参数final route = call.argument<String>("route");final params = call.argument<Map<String, dynamic>>("params");// 跳转到 Flutter 内部页面Navigator.pushNamed(navigatorKey.currentContext!, // 需提前定义全局 navigatorKeyroute!,arguments: params,);return "Flutter 页面已打开";}return null;});}
}
核心总结
场景 | 跳转方式 | 参数传递方式 |
---|---|---|
Flutter 内部 | Navigator.push / pushNamed | 构造函数、arguments、状态管理 |
Flutter → Android | MethodChannel 发送指令 | Map 格式参数通过 invokeMethod 传递 |
Android → Flutter | MethodChannel 发送指令 | Map 格式参数通过 invokeMethod 传递 |
跨平台跳转需确保 MethodChannel 名称一致,参数类型建议使用基础类型(String/Int/Map 等)以避免序列化问题。