在已有的原生 App 里嵌入 Flutter 页面的方法

在原生 App 中嵌入 Flutter 页面,通常使用 Flutter 提供的**平台通道(Platform Channels)**来实现原生代码与 Flutter 之间的交互。具体实现方式依赖于原生 App 的平台(如 Android 或 iOS),下面是两种常见的方法:

1. 使用 Flutter 插件(Flutter Module)

这种方法通过将 Flutter 作为一个模块嵌入到现有的原生应用中。这样可以让你在现有的原生应用里调用 Flutter 页面。

步骤:
  • 创建 Flutter 模块: 首先,你需要创建一个 Flutter 模块,这样就可以将 Flutter 页面嵌入到现有的原生应用中。

    你可以通过以下命令来创建 Flutter 模块:

    bash 复制代码
    flutter create --template module my_flutter

    这样会创建一个 Flutter 模块,目录结构类似:

    text 复制代码
    my_flutter/
    ├── .ios/
    ├── .android/
    └── lib/
  • 将 Flutter 模块添加到现有的原生 App 中:

    • 对于 Android

      1. 在原生项目的 settings.gradle 中包含 Flutter 模块:
      gradle 复制代码
      include ':app', ':my_flutter'
      setProjectDir(':my_flutter', file('path_to_flutter_module'))
      1. app/build.gradle 中添加对 Flutter 的依赖:
      gradle 复制代码
      dependencies {
        implementation project(':my_flutter')
      }
      1. 在原生代码中启动 Flutter 页面:
      java 复制代码
      import io.flutter.embedding.android.FlutterActivity;
      
      // 启动 Flutter 页面
      startActivity(
        FlutterActivity.createDefaultIntent(this)
      );
    • 对于 iOS

      1. 在原生 iOS 项目的 Podfile 中添加 Flutter 模块依赖:
      ruby 复制代码
      flutter_application_path = 'path_to_flutter_module'
      load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
      1. 在原生代码中启动 Flutter 页面:
      swift 复制代码
      import Flutter
      
      let flutterEngine = FlutterEngine(name: "my flutter engine")
      flutterEngine.run()
      
      let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
      self.present(flutterViewController, animated: true, completion: nil)

2. 使用 FlutterFragmentFlutterViewController(更细粒度的控制)

如果你想在原生应用中嵌入一个 Flutter 页面而不是整个 Flutter 模块,可以使用 FlutterFragment(Android)或 FlutterViewController(iOS)来嵌入单个 Flutter 页面。

Android:

你可以通过 FlutterFragment 来嵌入 Flutter 页面:

java 复制代码
import io.flutter.embedding.android.FlutterFragment;

FlutterFragment flutterFragment = FlutterFragment.withNewEngine().build();
getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.fragment_container, flutterFragment)
    .commit();
iOS:

你可以通过 FlutterViewController 来嵌入 Flutter 页面:

swift 复制代码
import Flutter

let flutterViewController = FlutterViewController()
self.navigationController?.pushViewController(flutterViewController, animated: true)

3. 使用平台通道与原生代码通信

在嵌入 Flutter 页面后,如果需要在 Flutter 与原生代码之间进行通信,可以使用平台通道(Platform Channels)。这允许你在 Flutter 页面与原生应用之间传递数据和调用方法。

  • Flutter 端:

    dart 复制代码
    import 'package:flutter/services.dart';
    
    static const platform = MethodChannel('com.example.myapp/channel');
    
    Future<void> _callNative() async {
      try {
        final result = await platform.invokeMethod('nativeMethod');
        print(result);
      } on PlatformException catch (e) {
        print("Failed to call native method: '${e.message}'.");
      }
    }
  • Android 端:

    java 复制代码
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
    import io.flutter.plugin.common.MethodChannel.Result;
    
    new MethodChannel(getFlutterEngine().getDartExecutor(), "com.example.myapp/channel")
        .setMethodCallHandler(
          (call, result) -> {
            if (call.method.equals("nativeMethod")) {
              result.success("Hello from Android");
            } else {
              result.notImplemented();
            }
          });
  • iOS 端:

    swift 复制代码
    import Flutter
    
    let channel = FlutterMethodChannel(name: "com.example.myapp/channel", binaryMessenger: flutterViewController.binaryMessenger)
    
    channel.setMethodCallHandler { (call, result) in
        if call.method == "nativeMethod" {
            result("Hello from iOS")
        } else {
            result(FlutterMethodNotImplemented)
        }
    }

这样,你就可以在原生 App 中嵌入 Flutter 页面,并与原生功能进行交互了。

相关推荐
我是苏苏21 分钟前
消息中间件RabbitMQ02:账号的注册、点对点推送信息
开发语言·后端·ruby
工藤新一¹38 分钟前
C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 14)
开发语言·c++·游戏引擎·游戏开发·sdl·实践项目
钢铁男儿1 小时前
C#核心技术解析:静态类型、dynamic与可空类型
开发语言·c#
只会写bug的靓仔1 小时前
mac 设置飞书默认浏览器(解决系统设置默认浏览器无效)
macos·飞书
卓越进步2 小时前
层级时间轮的 Golang 实现原理与实践
开发语言·后端·golang
zandy10112 小时前
嵌入式BI开发指南:如何通过衡石API将分析能力集成到业务系统?
开发语言·python·嵌入式
沉迷...2 小时前
el-input限制输入只能是数字 限制input只能输入数字
开发语言·前端·elementui
<但凡.2 小时前
C++修炼:list模拟实现
开发语言·数据结构·c++
byte轻骑兵2 小时前
【C++类和数据抽象】复制构造函数
开发语言·c++
EQ-雪梨蛋花汤2 小时前
【Flutter】Unity 三端封装方案:Android / iOS / Web
android·flutter·unity