在已有的原生 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 页面,并与原生功能进行交互了。

相关推荐
NoneCoder39 分钟前
JavaScript系列(86)--现代构建工具详解
开发语言·javascript·rust
Zhen (Evan) Wang40 分钟前
C#中提供的多种集合类以及适用场景
开发语言·c#
weixin_4440090043 分钟前
浏览器JS打不上断点,一点就跳到其他文件里。浏览器控制台 js打断点,指定的位置打不上断点,一打就跳到其他地方了。
开发语言·javascript·ecmascript
郑祎亦1 小时前
Java 关键字 volatile
java·开发语言·jvm
BTU_YC1 小时前
Failed to start The PHP FastCGI Process Manager.
开发语言·php
诗诗的博客1 小时前
jmeter聚合报告如何添加单位_性能测试连载(8)jmeter压力测试中的难点解析
java·开发语言
xidianhuihui2 小时前
go如何排查某个依赖是哪里引入的
开发语言·后端·golang
怡~2 小时前
Golang适配达梦数据库连接指定模式
开发语言·数据库·golang
姜来可期2 小时前
【Golang】go语言异常处理快速学习
开发语言·笔记·后端·学习·golang
ianozo2 小时前
BUU40 [CSCCTF 2019 Qual]FlaskLight1【SSTI】
开发语言·python