一、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")
// 启动原生 Activity
val 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()
)
// 发送参数到 Flutter
MethodChannel(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!, // 需提前定义全局 navigatorKey
route!,
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 等)以避免序列化问题。