Flutter 页面跳转及传参总结

发布于:2025-08-01 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、Flutter 内部页面跳转与传参
Flutter 内部页面跳转主要通过 Navigator 组件实现,参数传递可通过构造函数、路由参数或状态管理工具(如 Provider、GetX 等)。

  1. 基础跳转方式(无命名路由)
    使用 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("跳转到第二页"),
)
  1. 命名路由跳转
    在 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']}"),
      ),
    );
  }
}
  1. 返回数据给上一页
    通过 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 实现跨平台通信,完成页面跳转和参数传递。

  1. 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()
      }
    }
  }
}
  1. 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 等)以避免序列化问题。


网站公告

今日签到

点亮在社区的每一天
去签到