flutter-embedding-native-views by flutter/skills
npx skills add https://github.com/flutter/skills --skill flutter-embedding-native-views平台视图允许将原生视图(Android、iOS、macOS)直接嵌入 Flutter 应用,并支持从 Dart 层应用变换、裁剪和透明度效果。
根据您的性能和保真度要求选择合适的实现方式:
SurfaceFlinger 进行合成。
SurfaceView 存在问题(会破坏无障碍功能)。除非 Flutter 被渲染到 TextureView 中,否则文本放大镜会失效。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
UIViewShaderMask 和 ColorFiltered 小部件。BackdropFilter 存在合成限制。NSView)。
在复杂的 Dart 动画期间,可以通过将原生视图的屏幕截图渲染为占位符纹理来缓解性能下降。
使用全页模式或嵌入(多视图)模式将 Flutter 嵌入现有的网页应用(Vanilla JS、React、Angular 等)。
iframe。div)中。需要在引擎初始化时设置 multiViewEnabled: true。
app.addView() 和 app.removeView() 从 JavaScript 管理视图。runApp 替换为 runWidget。WidgetsBinding.instance.platformDispatcher.views 管理动态视图列表,并使用 ViewCollection 和 View 小部件进行渲染。按照此顺序工作流程在 Android 上实现平台视图。
任务进度:
如果使用混合合成,请使用 PlatformViewLink、AndroidViewSurface 和 PlatformViewsService.initSurfaceAndroidView。如果使用纹理层,请使用 AndroidView 小部件。
创建一个实现 io.flutter.plugin.platform.PlatformView 的类,该类返回您的原生 android.view.View。创建一个扩展 PlatformViewFactory 的工厂来实例化您的视图。
使用 flutterEngine.platformViewsController.registry.registerViewFactory 在您的 MainActivity.kt(或插件)中注册工厂。
注意:如果您的原生视图使用 SurfaceView 或 SurfaceTexture,当内容更改时,请在 View 或其父视图上手动调用 invalidate,因为它们不会自动失效。
按照此顺序工作流程在 iOS 上实现平台视图。
任务进度:
UiKitView 实现 Dart 小部件。FlutterPlatformView)和 Factory(FlutterPlatformViewFactory)。AppDelegate.swift 或插件注册器中注册平台视图。按照此顺序工作流程将 Flutter 嵌入现有的网页 DOM。
任务进度:
flutter_bootstrap.js 以启用多视图。main.dart 以使用 runWidget 和 ViewCollection。在 flutter_bootstrap.js 中,使用 multiViewEnabled: true 初始化引擎。使用返回的 app 对象来添加视图:app.addView({ hostElement: document.getElementById('my-div') })。
将 runApp() 替换为 runWidget()。创建一个根小部件,监听 WidgetsBindingObserver.didChangeMetrics。遍历 WidgetsBinding.instance.platformDispatcher.views 为每个附加的 FlutterView 创建一个 View 小部件,并将它们全部包装在一个 ViewCollection 中。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NativeAndroidView extends StatelessWidget {
@override
Widget build(BuildContext context) {
const String viewType = 'my_native_view';
final Map<String, dynamic> creationParams = <String, dynamic>{};
return AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
}
_flutter.loader.load({
onEntrypointLoaded: async function(engineInitializer) {
let engine = await engineInitializer.initializeEngine({
multiViewEnabled: true,
});
let app = await engine.runApp();
// 将视图添加到特定的 DOM 元素
let viewId = app.addView({
hostElement: document.querySelector('#flutter-host-container'),
initialData: { customData: 'Hello from JS' }
});
}
});
import 'dart:ui' show FlutterView;
import 'package:flutter/widgets.dart';
void main() {
runWidget(MultiViewApp(viewBuilder: (context) => const MyEmbeddedWidget()));
}
class MultiViewApp extends StatefulWidget {
final WidgetBuilder viewBuilder;
const MultiViewApp({super.key, required this.viewBuilder});
@override
State<MultiViewApp> createState() => _MultiViewAppState();
}
class _MultiViewAppState extends State<MultiViewApp> with WidgetsBindingObserver {
Map<Object, Widget> _views = {};
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_updateViews();
}
@override
void didChangeMetrics() => _updateViews();
void _updateViews() {
final newViews = <Object, Widget>{};
for (final FlutterView view in WidgetsBinding.instance.platformDispatcher.views) {
newViews[view.viewId] = _views[view.viewId] ?? View(
view: view,
child: Builder(builder: widget.viewBuilder),
);
}
setState(() => _views = newViews);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return ViewCollection(views: _views.values.toList(growable: false));
}
}
每周安装量
1.8K
代码仓库
GitHub 星标数
808
首次出现
12 天前
安全审计
安装于
codex1.7K
gemini-cli1.7K
opencode1.7K
github-copilot1.7K
cursor1.7K
kimi-cli1.7K
Platform Views allow embedding native views (Android, iOS, macOS) directly into a Flutter application, enabling the application of transforms, clips, and opacity from Dart.
Choose the appropriate implementation based on your performance and fidelity requirements:
SurfaceFlinger to compose both.
SurfaceView is problematic (breaks accessibility). Text magnifiers break unless Flutter is rendered into a TextureView.UIView is appended to the view hierarchy.
ShaderMask and ColorFiltered widgets are not supported. BackdropFilter has composition limitations.NSView).
Mitigate performance drops during complex Dart animations by rendering a screenshot of the native view as a placeholder texture while the animation runs.
Embed Flutter into existing web applications (Vanilla JS, React, Angular, etc.) using either Full Page mode or Embedded (Multi-view) mode.
iframe if you need to constrain the Flutter app without modifying the Flutter bootstrap process.divs). Requires multiViewEnabled: true during engine initialization.
app.addView() and app.removeView().runApp with runWidget.WidgetsBinding.instance.platformDispatcher.views and render them using ViewCollection and widgets.Follow this sequential workflow to implement a Platform View on Android.
Task Progress:
If using Hybrid Composition , use PlatformViewLink, AndroidViewSurface, and PlatformViewsService.initSurfaceAndroidView. If using Texture Layer , use the AndroidView widget.
Create a class implementing io.flutter.plugin.platform.PlatformView that returns your native android.view.View. Create a factory extending PlatformViewFactory to instantiate your view.
Register the factory in your MainActivity.kt (or plugin) using flutterEngine.platformViewsController.registry.registerViewFactory.
Note: If your native view usesSurfaceView or SurfaceTexture, manually call invalidate on the View or its parent when content changes, as they do not invalidate themselves automatically.
Follow this sequential workflow to implement a Platform View on iOS.
Task Progress:
UiKitView.FlutterPlatformView) and Factory (FlutterPlatformViewFactory).AppDelegate.swift or the plugin registrar.Follow this sequential workflow to embed Flutter into an existing web DOM.
Task Progress:
flutter_bootstrap.js to enable multi-view.main.dart to use runWidget and ViewCollection.In flutter_bootstrap.js, initialize the engine with multiViewEnabled: true. Use the returned app object to add views: app.addView({ hostElement: document.getElementById('my-div') }).
Replace runApp() with runWidget(). Create a root widget that listens to WidgetsBindingObserver.didChangeMetrics. Map over WidgetsBinding.instance.platformDispatcher.views to create a View widget for each attached FlutterView, and wrap them all in a ViewCollection.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NativeAndroidView extends StatelessWidget {
@override
Widget build(BuildContext context) {
const String viewType = 'my_native_view';
final Map<String, dynamic> creationParams = <String, dynamic>{};
return AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
}
_flutter.loader.load({
onEntrypointLoaded: async function(engineInitializer) {
let engine = await engineInitializer.initializeEngine({
multiViewEnabled: true,
});
let app = await engine.runApp();
// Add a view to a specific DOM element
let viewId = app.addView({
hostElement: document.querySelector('#flutter-host-container'),
initialData: { customData: 'Hello from JS' }
});
}
});
import 'dart:ui' show FlutterView;
import 'package:flutter/widgets.dart';
void main() {
runWidget(MultiViewApp(viewBuilder: (context) => const MyEmbeddedWidget()));
}
class MultiViewApp extends StatefulWidget {
final WidgetBuilder viewBuilder;
const MultiViewApp({super.key, required this.viewBuilder});
@override
State<MultiViewApp> createState() => _MultiViewAppState();
}
class _MultiViewAppState extends State<MultiViewApp> with WidgetsBindingObserver {
Map<Object, Widget> _views = {};
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_updateViews();
}
@override
void didChangeMetrics() => _updateViews();
void _updateViews() {
final newViews = <Object, Widget>{};
for (final FlutterView view in WidgetsBinding.instance.platformDispatcher.views) {
newViews[view.viewId] = _views[view.viewId] ?? View(
view: view,
child: Builder(builder: widget.viewBuilder),
);
}
setState(() => _views = newViews);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return ViewCollection(views: _views.values.toList(growable: false));
}
}
Weekly Installs
1.8K
Repository
GitHub Stars
808
First Seen
12 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex1.7K
gemini-cli1.7K
opencode1.7K
github-copilot1.7K
cursor1.7K
kimi-cli1.7K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
AI智能体长期记忆系统 - 精英级架构,融合6种方法,永不丢失上下文
1,200 周安装
AI新闻播客制作技能:实时新闻转对话式播客脚本与音频生成
1,200 周安装
Word文档处理器:DOCX创建、编辑、分析与修订痕迹处理全指南 | 自动化办公解决方案
1,200 周安装
React Router 框架模式指南:全栈开发、文件路由、数据加载与渲染策略
1,200 周安装
Nano Banana AI 图像生成工具:使用 Gemini 3 Pro 生成与编辑高分辨率图像
1,200 周安装
SVG Logo Designer - AI 驱动的专业矢量标识设计工具,生成可缩放品牌标识
1,200 周安装
View