如何在iOS/Android原生应用中嵌入Flutter Widget?
在iOS/Android原生App中嵌入Flutter Widget的实操步骤
通用前置准备
先创建一个Flutter Module(若尚未创建):
flutter create --template module flutter_module
在Flutter Module的lib/main.dart中,为不同Widget设置路由入口,方便原生端指定加载目标:
void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => const HomeWidget(), '/custom_widget': (context) => const CustomFlutterWidget(), }, ); } }
Android 端嵌入步骤
引入Flutter Module到原生项目
在原生Android项目的settings.gradle中添加:setBinding(new Binding([gradle: this])) evaluate(new File( settingsDir.parentFile, 'flutter_module/.android/include_flutter.groovy' ))接着在
app/build.gradle的dependencies区块中添加依赖:implementation project(':flutter')预初始化FlutterEngine并缓存
建议在Application类中提前初始化,避免首次加载卡顿:class MyApplication : Application() { override fun onCreate() { super.onCreate() // 初始化FlutterEngine val flutterEngine = FlutterEngine(this) // 指定要加载的Widget路由 flutterEngine.navigationChannel.setInitialRoute("/custom_widget") flutterEngine.dartExecutor.executeDartEntrypoint( DartExecutor.DartEntrypoint.createDefault() ) // 缓存Engine,供后续页面复用 FlutterEngineCache.getInstance().put("my_engine_id", flutterEngine) } }在布局中嵌入Flutter Widget
方式一:直接在XML布局中添加FlutterView<io.flutter.embedding.android.FlutterView android:id="@+id/flutter_view" android:layout_width="match_parent" android:layout_height="300dp" app:flutter_engine_id="my_engine_id" />方式二:用
FlutterFragment嵌入(适合Fragment场景)val flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build() supportFragmentManager.beginTransaction() .replace(R.id.flutter_container, flutterFragment) .commit()
iOS 端嵌入步骤
通过CocoaPods引入Flutter Module
在原生iOS项目的Podfile中添加:flutter_application_path = '../flutter_module' load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')在需要引入Flutter的target下添加:
install_all_flutter_pods(flutter_application_path)执行
pod install完成依赖安装。预初始化FlutterEngine并缓存
在AppDelegate中完成引擎初始化与缓存:import Flutter import FlutterPluginRegistrant @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // 声明FlutterEngine实例 lazy var flutterEngine = FlutterEngine(name: "my_engine_id") func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 启动引擎并指定加载的Widget路由 flutterEngine.run(withEntrypoint: nil, initialRoute: "/custom_widget") // 注册Flutter插件(如有需要) GeneratedPluginRegistrant.register(with: flutterEngine) return true } }在ViewController中嵌入Flutter Widget
方式一:添加FlutterView到视图层级import Flutter class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 获取缓存的FlutterEngine guard let engine = (UIApplication.shared.delegate as? AppDelegate)?.flutterEngine else { return } let flutterView = FlutterView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 300), engine: engine) view.addSubview(flutterView) } }方式二:用
FlutterViewController跳转(适合单独页面场景)let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil) present(flutterViewController, animated: true)
注意事项
- 尺寸适配:Android端通过布局参数控制FlutterView大小,iOS端通过frame约束;Flutter内部需做好Widget适配,避免内容超出边界。
- 生命周期管理:Android端需注意FlutterEngine与Activity/Fragment的生命周期绑定,防止内存泄漏;iOS端确保FlutterEngine在App生命周期内合理管理。
- 双向通信:原生与Flutter需传值时,使用
MethodChannel即可,两端分别注册监听和发送消息。
内容的提问来源于stack exchange,提问作者Joao Victor Guimaraes
相关产品推荐
相关产品推荐

