From 1b35cc2cc280a79d54bdc7ff6541d4dc50b1fb91 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 13 Jul 2018 20:41:55 -0700 Subject: [PATCH] Support keyboardAppearance field for iOS (#19244) --- .../flutter/lib/src/material/text_field.dart | 10 ++++++++++ .../lib/src/material/text_form_field.dart | 2 ++ .../flutter/lib/src/services/text_input.dart | 19 +++++++++++++++---- .../lib/src/widgets/editable_text.dart | 9 +++++++++ .../test/services/text_input_test.dart | 5 +++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index f9746421251..f82f011245e 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -115,6 +115,7 @@ class TextField extends StatefulWidget { this.onSubmitted, this.inputFormatters, this.enabled, + this.keyboardAppearance, }) : assert(keyboardType != null), assert(textInputAction != null), assert(textAlign != null), @@ -278,6 +279,13 @@ class TextField extends StatefulWidget { /// [Decoration.enabled] property. final bool enabled; + /// The appearance of the keyboard. + /// + /// This setting is only honored on iOS devices. + /// + /// If unset, defaults to the brightness of [ThemeData.primaryColorBrightness]. + final Brightness keyboardAppearance; + @override _TextFieldState createState() => new _TextFieldState(); @@ -468,6 +476,7 @@ class _TextFieldState extends State with AutomaticKeepAliveClientMixi assert(debugCheckHasMaterial(context)); final ThemeData themeData = Theme.of(context); final TextStyle style = widget.style ?? themeData.textTheme.subhead; + final Brightness keyboardAppearance = widget.keyboardAppearance ?? themeData.primaryColorBrightness; final TextEditingController controller = _effectiveController; final FocusNode focusNode = _effectiveFocusNode; final List formatters = widget.inputFormatters ?? []; @@ -497,6 +506,7 @@ class _TextFieldState extends State with AutomaticKeepAliveClientMixi onSelectionChanged: _handleSelectionChanged, inputFormatters: formatters, rendererIgnoresPointer: true, + keyboardAppearance: keyboardAppearance, ), ); diff --git a/packages/flutter/lib/src/material/text_form_field.dart b/packages/flutter/lib/src/material/text_form_field.dart index e8f0aa2c48e..d9afab10d2f 100644 --- a/packages/flutter/lib/src/material/text_form_field.dart +++ b/packages/flutter/lib/src/material/text_form_field.dart @@ -69,6 +69,7 @@ class TextFormField extends FormField { FormFieldValidator validator, List inputFormatters, bool enabled, + Brightness keyboardAppearance, }) : assert(initialValue == null || controller == null), assert(keyboardType != null), assert(textAlign != null), @@ -106,6 +107,7 @@ class TextFormField extends FormField { onSubmitted: onFieldSubmitted, inputFormatters: inputFormatters, enabled: enabled, + keyboardAppearance: keyboardAppearance, ); }, ); diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart index 702e4f552be..20e38c8868f 100644 --- a/packages/flutter/lib/src/services/text_input.dart +++ b/packages/flutter/lib/src/services/text_input.dart @@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart'; import 'message_codec.dart'; import 'system_channels.dart'; +import 'system_chrome.dart'; import 'text_editing.dart'; export 'dart:ui' show TextAffinity; @@ -104,7 +105,7 @@ class TextInputType { String get _name => 'TextInputType.${_names[index]}'; /// Returns a representation of this object as a JSON object. - Map toJSON() { + Map toJson() { return { 'name': _name, 'signed': signed, @@ -341,9 +342,11 @@ class TextInputConfiguration { this.autocorrect = true, this.actionLabel, this.inputAction = TextInputAction.done, + this.keyboardAppearance = Brightness.light, }) : assert(inputType != null), assert(obscureText != null), assert(autocorrect != null), + assert(keyboardAppearance != null), assert(inputAction != null); /// The type of information for which to optimize the text input control. @@ -365,14 +368,22 @@ class TextInputConfiguration { /// What kind of action to request for the action button on the IME. final TextInputAction inputAction; + /// The appearance of the keyboard. + /// + /// This setting is only honored on iOS devices. + /// + /// Defaults to [Brightness.light]. + final Brightness keyboardAppearance; + /// Returns a representation of this object as a JSON object. - Map toJSON() { + Map toJson() { return { - 'inputType': inputType.toJSON(), + 'inputType': inputType.toJson(), 'obscureText': obscureText, 'autocorrect': autocorrect, 'actionLabel': actionLabel, 'inputAction': inputAction.toString(), + 'keyboardAppearance': keyboardAppearance.toString(), }; } } @@ -675,7 +686,7 @@ class TextInput { _clientHandler._currentConnection = connection; SystemChannels.textInput.invokeMethod( 'TextInput.setClient', - [ connection._id, configuration.toJSON() ], + [ connection._id, configuration.toJson() ], ); return connection; } diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index 1c821ae9d54..ed2262e3b26 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -210,6 +210,7 @@ class EditableText extends StatefulWidget { this.rendererIgnoresPointer = false, this.cursorWidth = 1.0, this.cursorRadius, + this.keyboardAppearance = Brightness.light, }) : assert(controller != null), assert(focusNode != null), assert(obscureText != null), @@ -365,6 +366,13 @@ class EditableText extends StatefulWidget { /// By default, the cursor has a Radius of zero. final Radius cursorRadius; + /// The appearance of the keyboard. + /// + /// This setting is only honored on iOS devices. + /// + /// Defaults to [Brightness.light]. + final Brightness keyboardAppearance; + @override EditableTextState createState() => new EditableTextState(); @@ -557,6 +565,7 @@ class EditableTextState extends State with AutomaticKeepAliveClien inputType: widget.keyboardType, obscureText: widget.obscureText, autocorrect: widget.autocorrect, + keyboardAppearance: widget.keyboardAppearance, inputAction: widget.keyboardType == TextInputType.multiline ? TextInputAction.newline : widget.textInputAction, diff --git a/packages/flutter/test/services/text_input_test.dart b/packages/flutter/test/services/text_input_test.dart index 49be2a652bb..159176d0533 100644 --- a/packages/flutter/test/services/text_input_test.dart +++ b/packages/flutter/test/services/text_input_test.dart @@ -13,6 +13,7 @@ void main() { expect(configuration.obscureText, false); expect(configuration.autocorrect, true); expect(configuration.actionLabel, null); + expect(configuration.keyboardAppearance, Brightness.light); }); test('text serializes to JSON', () async { @@ -22,7 +23,7 @@ void main() { autocorrect: false, actionLabel: 'xyzzy', ); - final Map json = configuration.toJSON(); + final Map json = configuration.toJson(); expect(json['inputType'], { 'name': 'TextInputType.text', 'signed': null, 'decimal': null }); @@ -38,7 +39,7 @@ void main() { autocorrect: false, actionLabel: 'xyzzy', ); - final Map json = configuration.toJSON(); + final Map json = configuration.toJson(); expect(json['inputType'], { 'name': 'TextInputType.number', 'signed': false, 'decimal': true });