向 Android 应用添加 Flutter View
了解如何通过 Flutter View 进行高级集成。
通过 FlutterView 集成比前文介绍的 FlutterActivity 和 FlutterFragment 方式需要更多工作。
从根本上说,Dart 侧的 Flutter 框架需要访问各种 activity 级别的事件与生命周期才能正常工作。由于 FlutterView(它是一个 android.view.View)可以添加到开发者应用拥有的任意 activity 中,而 FlutterView 无法访问 activity 级别的事件,因此开发者必须手动将这些连接桥接到 FlutterEngine。
你如何将应用的 activity 事件传递给 FlutterView,取决于你的应用本身。
示例
#
与 FlutterActivity 和 FlutterFragment 的指南不同,FlutterView 集成更适合用示例项目来演示。
示例项目位于 https://github.com/flutter/samples/tree/main/add_to_app/android_view,演示了简单的 FlutterView 集成:在 RecycleView 卡片列表的部分 cell 中使用 FlutterView,如上方 gif 所示。
通用做法
#
FlutterView 级别集成的要点是:你必须在自己的应用代码中重现 Activity、FlutterView
与 FlutterEngine
之间在 FlutterActivityAndFragmentDelegate
中的各种交互。FlutterActivityAndFragmentDelegate
中的连接在使用 FlutterActivity
或 FlutterFragment
时会自动完成;但本场景下 FlutterView
被添加到你应用中的 Activity 或 Fragment,因此你必须手动重建这些连接。否则 FlutterView
将无法渲染任何内容,或缺少其他功能。
示例 FlutterViewEngine
类展示了一种可能的实现:在 Activity、FlutterView
与 FlutterEngine
之间建立应用特定的连接。
需要实现的 API
#要让 Flutter 至少能绘制任何内容,最低限度的实现包括:
-
Call
attachToFlutterEnginewhen theFlutterViewis added to a resumedActivity's view hierarchy and is visible; and -
Call
appIsResumedon theFlutterEngine'slifecycleChannelfield when theActivityhosting theFlutterViewis visible. -
当
FlutterView被添加到已 resumed 的Activity视图层级且可见时,调用attachToFlutterEngine;以及 -
当承载
FlutterView的Activity可见时,在FlutterEngine的lifecycleChannel字段上调用appIsResumed。
当 FlutterView 或 Activity 不再可见时,还必须调用反向的 detachFromFlutterEngine
以及 LifecycleChannel
类上的其他生命周期方法,以避免资源泄漏。
此外,请参阅 FlutterViewEngine
演示类或 FlutterActivityAndFragmentDelegate
中的其余实现,以确保剪贴板、系统 UI 叠加层、插件等其他功能正常工作。
按内容自适应尺寸的 View
#
通常,FlutterView
需要通过自身尺寸或匹配父级尺寸来固定大小,如 示例项目
所示。不过,现在可以让 FlutterView 根据内容自行确定尺寸:对高度或宽度使用 content_wrap,FlutterView
即可自适应,如 按内容定尺寸示例项目
所示。
-
To enable Content-sized view when deploying your app, add the following setting to your project's
AndroidManifest.xmlfile under the<application>tag: -
在部署应用时 启用 按内容自适应尺寸的 View,请在项目
AndroidManifest.xml的<application>标签下添加以下设置:
<meta-data
android:name="io.flutter.embedding.android.EnableContentSizing"
android:value="true" />
限制
#由于按内容定尺寸的 Flutter View 要求 Flutter 应用能够自行确定尺寸,部分 widget 不受支持。
A widget with unbounded size, like a
ListView.A widget that defers to its child for the size, like
LayoutBuilder.尺寸无界的 widget,例如
ListView。将尺寸委托给子 widget 的 widget,例如
LayoutBuilder。
实践中,这意味着不少常用 widget 不受支持,例如 ScaffoldBuilder、CupertinoTimerPicker,或任何内部依赖 LayoutBuilder
的 widget。如有疑问,可用 UnconstrainedBox 测试某 widget 是否适用于按内容定尺寸的 View,如下例所示:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context)
=> MaterialApp(home: MyPage());
}
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: UnconstrainedBox(
// TODO: Edit this line to check if a widget
// can cause problems with content-sized views.
child: Text('This works!'),
// child: Column(children: [Column(children: [Expanded(child: Text('This blows up!'))])]),
// child: ListView(children: [Text('This blows up!')]),
)
);
}
}
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-04。查看文档源码 或者 为本页面内容提出建议。