Unverified Commit 734df6f5 authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Allow Flutter focus to interop with Android view hierarchies (#84055)

parent 17b024a5
......@@ -537,7 +537,7 @@ class _AndroidViewState extends State<AndroidView> {
}
SystemChannels.textInput.invokeMethod<void>(
'TextInput.setPlatformViewClient',
_id,
<String, dynamic>{'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<PlatformViewLink> {
if (!isFocused) {
_controller?.clearFocus();
}
SystemChannels.textInput.invokeMethod<void>(
'TextInput.setPlatformViewClient',
<String, dynamic>{'platformViewId': _id},
);
}
void _handlePlatformFocusChanged(bool isFocused){
......
......@@ -1074,10 +1074,10 @@ void main() {
containerFocusNode.requestFocus();
await tester.pump();
late int lastPlatformViewTextClient;
late Map<String, dynamic> lastPlatformViewTextClient;
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) {
if (call.method == 'TextInput.setPlatformViewClient') {
lastPlatformViewTextClient = call.arguments as int;
lastPlatformViewTextClient = call.arguments as Map<String, dynamic>;
}
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 <Factory<OneSequenceGestureRecognizer>>{},
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<String, dynamic> lastPlatformViewTextClient;
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) {
if (call.method == 'TextInput.setPlatformViewClient') {
lastPlatformViewTextClient = call.arguments as Map<String, dynamic>;
}
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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment