Unverified Commit 4d9c3cc3 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Always honor explicitly set keyboardType and inputAction for TextField (#20547)

With this change you can now create "wrapping" text fields that do not show the new line button:

```dart
new TextField(
  maxLines: null,
  keyboardType: TextInputType.text,
);
```
parent 2f3dd2c1
...@@ -71,9 +71,7 @@ class TextField extends StatefulWidget { ...@@ -71,9 +71,7 @@ class TextField extends StatefulWidget {
/// ///
/// The [maxLines] property can be set to null to remove the restriction on /// The [maxLines] property can be set to null to remove the restriction on
/// the number of lines. By default, it is one, meaning this is a single-line /// the number of lines. By default, it is one, meaning this is a single-line
/// text field. [maxLines] must not be zero. If [maxLines] is not one, then /// text field. [maxLines] must not be zero.
/// [keyboardType] is ignored, and the [TextInputType.multiline] keyboard
/// type is used.
/// ///
/// The [maxLength] property is set to null by default, which means the /// The [maxLength] property is set to null by default, which means the
/// number of characters allowed in the text field is not restricted. If /// number of characters allowed in the text field is not restricted. If
...@@ -89,8 +87,8 @@ class TextField extends StatefulWidget { ...@@ -89,8 +87,8 @@ class TextField extends StatefulWidget {
/// characters may be entered, and the error counter and divider will /// characters may be entered, and the error counter and divider will
/// switch to the [decoration.errorStyle] when the limit is exceeded. /// switch to the [decoration.errorStyle] when the limit is exceeded.
/// ///
/// The [keyboardType], [textAlign], [autofocus], [obscureText], and /// The [textAlign], [autofocus], [obscureText], and [autocorrect] arguments
/// [autocorrect] arguments must not be null. /// must not be null.
/// ///
/// See also: /// See also:
/// ///
...@@ -101,8 +99,8 @@ class TextField extends StatefulWidget { ...@@ -101,8 +99,8 @@ class TextField extends StatefulWidget {
this.controller, this.controller,
this.focusNode, this.focusNode,
this.decoration = const InputDecoration(), this.decoration = const InputDecoration(),
TextInputType keyboardType = TextInputType.text, TextInputType keyboardType,
this.textInputAction = TextInputAction.done, this.textInputAction,
this.textCapitalization = TextCapitalization.none, this.textCapitalization = TextCapitalization.none,
this.style, this.style,
this.textAlign = TextAlign.start, this.textAlign = TextAlign.start,
...@@ -122,9 +120,7 @@ class TextField extends StatefulWidget { ...@@ -122,9 +120,7 @@ class TextField extends StatefulWidget {
this.cursorColor, this.cursorColor,
this.keyboardAppearance, this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0), this.scrollPadding = const EdgeInsets.all(20.0),
}) : assert(keyboardType != null), }) : assert(textAlign != null),
assert(textInputAction != null),
assert(textAlign != null),
assert(autofocus != null), assert(autofocus != null),
assert(obscureText != null), assert(obscureText != null),
assert(autocorrect != null), assert(autocorrect != null),
...@@ -132,7 +128,7 @@ class TextField extends StatefulWidget { ...@@ -132,7 +128,7 @@ class TextField extends StatefulWidget {
assert(scrollPadding != null), assert(scrollPadding != null),
assert(maxLines == null || maxLines > 0), assert(maxLines == null || maxLines > 0),
assert(maxLength == null || maxLength > 0), assert(maxLength == null || maxLength > 0),
keyboardType = maxLines == 1 ? keyboardType : TextInputType.multiline, keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
super(key: key); super(key: key);
/// Controls the text being edited. /// Controls the text being edited.
...@@ -156,14 +152,14 @@ class TextField extends StatefulWidget { ...@@ -156,14 +152,14 @@ class TextField extends StatefulWidget {
/// The type of keyboard to use for editing the text. /// The type of keyboard to use for editing the text.
/// ///
/// Defaults to [TextInputType.text]. Must not be null. If /// Defaults to [TextInputType.text] if [maxLines] is one and
/// [maxLines] is not one, then [keyboardType] is ignored, and the /// [TextInputType.multiline] otherwise.
/// [TextInputType.multiline] keyboard type is used.
final TextInputType keyboardType; final TextInputType keyboardType;
/// The type of action button to use for the keyboard. /// The type of action button to use for the keyboard.
/// ///
/// Defaults to [TextInputAction.done]. Must not be null. /// Defaults to [TextInputAction.newline] if [keyboardType] is
/// [TextInputType.multiline] and [TextInputAction.done] otherwise.
final TextInputAction textInputAction; final TextInputAction textInputAction;
/// Configures how the platform keyboard will select an uppercase or /// Configures how the platform keyboard will select an uppercase or
......
...@@ -54,9 +54,9 @@ class TextFormField extends FormField<String> { ...@@ -54,9 +54,9 @@ class TextFormField extends FormField<String> {
String initialValue, String initialValue,
FocusNode focusNode, FocusNode focusNode,
InputDecoration decoration = const InputDecoration(), InputDecoration decoration = const InputDecoration(),
TextInputType keyboardType = TextInputType.text, TextInputType keyboardType,
TextCapitalization textCapitalization = TextCapitalization.none, TextCapitalization textCapitalization = TextCapitalization.none,
TextInputAction textInputAction = TextInputAction.done, TextInputAction textInputAction,
TextStyle style, TextStyle style,
TextAlign textAlign = TextAlign.start, TextAlign textAlign = TextAlign.start,
bool autofocus = false, bool autofocus = false,
...@@ -75,8 +75,6 @@ class TextFormField extends FormField<String> { ...@@ -75,8 +75,6 @@ class TextFormField extends FormField<String> {
Brightness keyboardAppearance, Brightness keyboardAppearance,
EdgeInsets scrollPadding = const EdgeInsets.all(20.0), EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
}) : assert(initialValue == null || controller == null), }) : assert(initialValue == null || controller == null),
assert(keyboardType != null),
assert(textInputAction != null),
assert(textAlign != null), assert(textAlign != null),
assert(autofocus != null), assert(autofocus != null),
assert(obscureText != null), assert(obscureText != null),
......
...@@ -201,7 +201,7 @@ class EditableText extends StatefulWidget { ...@@ -201,7 +201,7 @@ class EditableText extends StatefulWidget {
this.selectionColor, this.selectionColor,
this.selectionControls, this.selectionControls,
TextInputType keyboardType, TextInputType keyboardType,
this.textInputAction = TextInputAction.done, this.textInputAction,
this.textCapitalization = TextCapitalization.none, this.textCapitalization = TextCapitalization.none,
this.onChanged, this.onChanged,
this.onEditingComplete, this.onEditingComplete,
...@@ -597,9 +597,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -597,9 +597,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
inputType: widget.keyboardType, inputType: widget.keyboardType,
obscureText: widget.obscureText, obscureText: widget.obscureText,
autocorrect: widget.autocorrect, autocorrect: widget.autocorrect,
inputAction: widget.keyboardType == TextInputType.multiline inputAction: widget.textInputAction ?? (widget.keyboardType == TextInputType.multiline
? TextInputAction.newline ? TextInputAction.newline
: widget.textInputAction, : TextInputAction.done
),
textCapitalization: widget.textCapitalization, textCapitalization: widget.textCapitalization,
) )
)..setEditingState(localValue); )..setEditingState(localValue);
...@@ -1036,4 +1037,4 @@ class _Editable extends LeafRenderObjectWidget { ...@@ -1036,4 +1037,4 @@ class _Editable extends LeafRenderObjectWidget {
..cursorWidth = cursorWidth ..cursorWidth = cursorWidth
..cursorRadius = cursorRadius; ..cursorRadius = cursorRadius;
} }
} }
\ No newline at end of file
...@@ -292,6 +292,65 @@ void main() { ...@@ -292,6 +292,65 @@ void main() {
equals('TextInputAction.newline')); equals('TextInputAction.newline'));
}); });
testWidgets('Multiline keyboard with newline action is requested when maxLines = null', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new FocusScope(
node: focusScopeNode,
autofocus: true,
child: new EditableText(
controller: controller,
focusNode: focusNode,
maxLines: null,
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.multiline'));
expect(tester.testTextInput.setClientArgs['inputAction'],
equals('TextInputAction.newline'));
});
testWidgets('Text keyboard is requested when explicitly set and maxLines = null', (WidgetTester tester) async {
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new FocusScope(
node: focusScopeNode,
autofocus: true,
child: new EditableText(
controller: controller,
focusNode: focusNode,
maxLines: null,
keyboardType: TextInputType.text,
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.text'));
expect(tester.testTextInput.setClientArgs['inputAction'],
equals('TextInputAction.done'));
});
testWidgets( testWidgets(
'Correct keyboard is requested when set explicitly and maxLines > 1', 'Correct keyboard is requested when set explicitly and maxLines > 1',
(WidgetTester tester) async { (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