diff --git a/packages/flutter/lib/src/services/platform_views.dart b/packages/flutter/lib/src/services/platform_views.dart index bcd33631e8b..ef7dfba0689 100644 --- a/packages/flutter/lib/src/services/platform_views.dart +++ b/packages/flutter/lib/src/services/platform_views.dart @@ -179,6 +179,24 @@ class PlatformViewsService { return controller; } + /// Whether the render surface of the Android `FlutterView` should be converted to a `FlutterImageView`. + /// + /// When adding platform views using + /// [Hybrid Composition](https://flutter.dev/docs/development/platform-integration/platform-views), + /// the engine converts the render surface to a `FlutterImageView` to improve + /// animation synchronization between Flutter widgets and the Android platform + /// views. On Android versions < 10, this can have some performance issues. + /// This flag allows disabling this conversion. + /// + /// Defaults to true. + static Future synchronizeToNativeViewHierarchy(bool yes) { + assert(defaultTargetPlatform == TargetPlatform.android); + return SystemChannels.platform_views.invokeMethod( + 'synchronizeToNativeViewHierarchy', + yes, + ); + } + // TODO(amirh): reference the iOS plugin API for registering a UIView factory once it lands. /// This is work in progress, not yet ready to be used, and requires a custom engine build. Creates a controller for a new iOS UIView. /// diff --git a/packages/flutter/test/services/fake_platform_views.dart b/packages/flutter/test/services/fake_platform_views.dart index 70992016aa9..dec83b3bf0c 100644 --- a/packages/flutter/test/services/fake_platform_views.dart +++ b/packages/flutter/test/services/fake_platform_views.dart @@ -141,6 +141,8 @@ class FakeAndroidPlatformViewsController { int? lastClearedFocusViewId; + bool synchronizeToNativeViewHierarchy = true; + void registerViewType(String viewType) { _registeredViewTypes.add(viewType); } @@ -166,6 +168,8 @@ class FakeAndroidPlatformViewsController { return _setDirection(call); case 'clearFocus': return _clearFocus(call); + case 'synchronizeToNativeViewHierarchy': + return _synchronizeToNativeViewHierarchy(call); } return Future.sync(() => null); } @@ -299,6 +303,11 @@ class FakeAndroidPlatformViewsController { lastClearedFocusViewId = id; return Future.sync(() => null); } + + Future _synchronizeToNativeViewHierarchy(MethodCall call) { + synchronizeToNativeViewHierarchy = call.arguments as bool; + return Future.sync(() => null); + } } class FakeIosPlatformViewsController { diff --git a/packages/flutter/test/services/platform_views_test.dart b/packages/flutter/test/services/platform_views_test.dart index 47ac3c1ee41..af8f58a3db7 100644 --- a/packages/flutter/test/services/platform_views_test.dart +++ b/packages/flutter/test/services/platform_views_test.dart @@ -218,6 +218,11 @@ void main() { ]), ); }); + + test('synchronizeToNativeViewHierarchy', () async { + await PlatformViewsService.synchronizeToNativeViewHierarchy(false); + expect(viewsController.synchronizeToNativeViewHierarchy, false); + }); }); group('iOS', () {