diff --git a/packages/flutter/lib/src/widgets/platform_view.dart b/packages/flutter/lib/src/widgets/platform_view.dart index aa5758b8e9..7e67d095b1 100644 --- a/packages/flutter/lib/src/widgets/platform_view.dart +++ b/packages/flutter/lib/src/widgets/platform_view.dart @@ -537,7 +537,7 @@ class _AndroidViewState extends State { } SystemChannels.textInput.invokeMethod( 'TextInput.setPlatformViewClient', - _id, + {'platformViewId': _id, 'usesVirtualDisplay': true}, ).catchError((dynamic e) { if (e is MissingPluginException) { // We land the framework part of Android platform views keyboard @@ -893,6 +893,10 @@ class _PlatformViewLinkState extends State { if (!isFocused) { _controller?.clearFocus(); } + SystemChannels.textInput.invokeMethod( + 'TextInput.setPlatformViewClient', + {'platformViewId': _id}, + ); } void _handlePlatformFocusChanged(bool isFocused){ diff --git a/packages/flutter/test/widgets/platform_view_test.dart b/packages/flutter/test/widgets/platform_view_test.dart index c259020371..d3cfbce40d 100644 --- a/packages/flutter/test/widgets/platform_view_test.dart +++ b/packages/flutter/test/widgets/platform_view_test.dart @@ -1074,10 +1074,10 @@ void main() { containerFocusNode.requestFocus(); await tester.pump(); - late int lastPlatformViewTextClient; + late Map lastPlatformViewTextClient; tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) { if (call.method == 'TextInput.setPlatformViewClient') { - lastPlatformViewTextClient = call.arguments as int; + lastPlatformViewTextClient = call.arguments as Map; } return null; }); @@ -1085,7 +1085,11 @@ void main() { viewsController.invokeViewFocused(currentViewId + 1); await tester.pump(); - expect(lastPlatformViewTextClient, currentViewId + 1); + expect(lastPlatformViewTextClient.containsKey('platformViewId'), true); + expect(lastPlatformViewTextClient['platformViewId'], currentViewId + 1); + + expect(lastPlatformViewTextClient.containsKey('usesVirtualDisplay'), true); + expect(lastPlatformViewTextClient['usesVirtualDisplay'], true); }); testWidgets('AndroidView clears platform focus when unfocused', (WidgetTester tester) async { @@ -2560,6 +2564,57 @@ void main() { expect(platformViewFocusNode.hasFocus, false); expect(controller.focusCleared, true); }); + + testWidgets('PlatformViewLink sets a platform view text input client when focused', (WidgetTester tester) async { + late FakePlatformViewController controller; + late int viewId; + + final PlatformViewLink platformViewLink = PlatformViewLink( + viewType: 'test', + onCreatePlatformView: (PlatformViewCreationParams params) { + viewId = params.id; + params.onPlatformViewCreated(params.id); + controller = FakePlatformViewController(params.id); + return controller; + }, + surfaceFactory: (BuildContext context, PlatformViewController controller) { + return PlatformViewSurface( + gestureRecognizers: const >{}, + controller: controller, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, + ); + await tester.pumpWidget(SizedBox(width: 300, height: 300, child: platformViewLink)); + + final Focus platformViewFocusWidget = tester.widget( + find.descendant( + of: find.byType(PlatformViewLink), + matching: find.byType(Focus), + ), + ); + + final FocusNode? focusNode = platformViewFocusWidget.focusNode; + expect(focusNode, isNotNull); + expect(focusNode!.hasFocus, false); + + late Map lastPlatformViewTextClient; + tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) { + if (call.method == 'TextInput.setPlatformViewClient') { + lastPlatformViewTextClient = call.arguments as Map; + } + return null; + }); + + platformViewFocusWidget.focusNode!.requestFocus(); + await tester.pump(); + + expect(focusNode.hasFocus, true); + expect(lastPlatformViewTextClient.containsKey('platformViewId'), true); + expect(lastPlatformViewTextClient['platformViewId'], viewId); + + expect(lastPlatformViewTextClient.containsKey('usesVirtualDisplay'), false); + }); }); testWidgets('Platform views respect hitTestBehavior', (WidgetTester tester) async {