From b2497822e84f18f543a8dd6eaaa34977c04054d2 Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Mon, 29 Jul 2019 15:15:57 -0700 Subject: [PATCH] Android visible password input type support (#36695) Android devices can now use the VisibleText input keyboard type. --- .../flutter/lib/src/services/text_input.dart | 9 +++-- .../test/widgets/editable_text_test.dart | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart index 6c67b93925..0a95f75877 100644 --- a/packages/flutter/lib/src/services/text_input.dart +++ b/packages/flutter/lib/src/services/text_input.dart @@ -96,14 +96,19 @@ class TextInputType { /// Requests a keyboard with ready access to the "/" and "." keys. static const TextInputType url = TextInputType._(6); + /// Optimize for passwords that are visible to the user. + /// + /// Requests a keyboard with ready access to both letters and numbers. + static const TextInputType visiblePassword = TextInputType._(7); + /// All possible enum values. static const List values = [ - text, multiline, number, phone, datetime, emailAddress, url, + text, multiline, number, phone, datetime, emailAddress, url, visiblePassword, ]; // Corresponding string name for each of the [values]. static const List _names = [ - 'text', 'multiline', 'number', 'phone', 'datetime', 'emailAddress', 'url', + 'text', 'multiline', 'number', 'phone', 'datetime', 'emailAddress', 'url', 'visiblePassword', ]; // Enum value name, this is what enum.toString() would normally return. diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index a1301d9bed..94aae4b547 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -268,6 +268,39 @@ void main() { equals('TextInputAction.newline')); }); + testWidgets('visiblePassword keyboard is requested when set explicitly', (WidgetTester tester) async { + await tester.pumpWidget( + MediaQuery( + data: const MediaQueryData(devicePixelRatio: 1.0), + child: Directionality( + textDirection: TextDirection.ltr, + child: FocusScope( + node: focusScopeNode, + autofocus: true, + child: EditableText( + controller: controller, + backgroundCursorColor: Colors.grey, + focusNode: focusNode, + keyboardType: TextInputType.visiblePassword, + style: textStyle, + cursorColor: cursorColor, + ), + ), + ), + ), + ); + + await tester.tap(find.byType(EditableText)); + await tester.showKeyboard(find.byType(EditableText)); + controller.text = 'test'; + await tester.idle(); + expect(tester.testTextInput.editingState['text'], equals('test')); + expect(tester.testTextInput.setClientArgs['inputType']['name'], + equals('TextInputType.visiblePassword')); + expect(tester.testTextInput.setClientArgs['inputAction'], + equals('TextInputAction.done')); + }); + testWidgets('selection overlay will update when text grow bigger', (WidgetTester tester) async { final TextEditingController controller = TextEditingController.fromValue( const TextEditingValue(