diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart index 42de350..fc5a6be 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart @@ -156,6 +156,9 @@ class _OnscreenKeyboardState extends State final _pressedActionKeys = {}; + @override + KeyboardLayout get layout => _layout; + void _onKeyDown(OnscreenKeyboardKey key) { switch (key) { case TextKey(): diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart index 160650b..4ef0d95 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart @@ -12,6 +12,9 @@ abstract interface class OnscreenKeyboardController { /// Closes the onscreen keyboard. void close(); + /// The current layout of the onscreen keyboard. + KeyboardLayout get layout; + /// Sets the alignment of the onscreen keyboard. /// /// [alignment] defines where the keyboard should appear in the app. diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart index 98da012..06ffc01 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart @@ -30,6 +30,7 @@ class OnscreenKeyboardTextField extends StatefulWidget { const OnscreenKeyboardTextField({ super.key, this.enableOnscreenKeyboard = true, + this.onscreenKeyboardMode, this.groupId = EditableText, this.controller, this.focusNode, @@ -122,6 +123,13 @@ class OnscreenKeyboardTextField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; + /// Changes the [KeyboardMode] to the one specified on [onscreenKeyboardMode] + /// when the [OnscreenKeyboardTextFormField] is selected. + /// + /// If none is specified the keyboard will use the first mode + /// specified on the layout mode list. + final String? onscreenKeyboardMode; + /// The configuration for the magnifier of this text field. /// /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] @@ -699,8 +707,13 @@ class _OnscreenKeyboardTextFieldState extends State void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { + final mode = + widget.onscreenKeyboardMode ?? + _keyboard.layout.modes.entries.first.key; + _keyboard ..attachTextField(this) + ..setModeNamed(mode) ..open(); } else { _keyboard.close(); diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart index a137ae2..83cad29 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart @@ -32,6 +32,7 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { super.key, this.formFieldKey, this.enableOnscreenKeyboard = true, + this.onscreenKeyboardMode, this.groupId = EditableText, this.controller, this.initialValue, @@ -140,6 +141,13 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; + /// Changes the [KeyboardMode] to the one specified on [onscreenKeyboardMode] + /// when the [OnscreenKeyboardTextFormField] is selected. + /// + /// If none is specified the keyboard will use the first mode + /// specified on the layout mode list. + final String? onscreenKeyboardMode; + /// {@macro flutter.widgets.editableText.groupId} final Object groupId; @@ -753,8 +761,13 @@ class _OnscreenKeyboardTextFormFieldState void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { + final mode = + widget.onscreenKeyboardMode ?? + _keyboard.layout.modes.entries.first.key; + _keyboard ..attachTextField(this) + ..setModeNamed(mode) ..open(); } else { _keyboard.close(); diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart index 1f97323..30e8cc1 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart @@ -112,5 +112,34 @@ void main() { expect(state.maxLines, 3); }, ); + testWidgets( + 'should switch to onscreenKeyboardMode when focused', + (tester) async { + await tester.pumpWidget( + MaterialApp( + builder: OnscreenKeyboard.builder( + width: (_) => 200, + layout: const MobileKeyboardLayout(), + ), + home: const Scaffold( + body: OnscreenKeyboardTextField( + onscreenKeyboardMode: 'symbols', + ), + ), + ), + ); + + await tester.tap(find.byType(OnscreenKeyboardTextField)); + await tester.pumpAndSettle(); + + // Check if the keyboard is in symbols mode by + // finding a key unique to that mode. + // '@' is the primary character of a key in symbols mode, but secondary + // in alphabets mode. + expect(find.text('@'), findsOneWidget); + // 'q' is in the alphabets mode, so it should not be found + expect(find.text('q'), findsNothing); + }, + ); }); } diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart index ecbf5b8..efb8ddb 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart @@ -202,5 +202,35 @@ void main() { expect(find.text('initial value'), findsOneWidget); }, ); + + testWidgets( + 'should switch to onscreenKeyboardMode when focused', + (tester) async { + await tester.pumpWidget( + MaterialApp( + builder: OnscreenKeyboard.builder( + width: (_) => 200, + layout: const MobileKeyboardLayout(), + ), + home: const Scaffold( + body: OnscreenKeyboardTextFormField( + onscreenKeyboardMode: 'symbols', + ), + ), + ), + ); + + await tester.tap(find.byType(OnscreenKeyboardTextFormField)); + await tester.pumpAndSettle(); + + // Check if the keyboard is in symbols mode by + // finding a key unique to that mode. + // '@' is the primary character of a key in symbols mode, but secondary + // in alphabets mode. + expect(find.text('@'), findsOneWidget); + // 'q' is in the alphabets mode, so it should not be found + expect(find.text('q'), findsNothing); + }, + ); }); }