[CP] Remove exclamation marks (#107683) (#113553)
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
Co-authored-by: Casey Hillers <chillers@google.com>
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index dbbb4b2..88bcff3 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -567,11 +567,11 @@
required this.floatingLabelHeight,
required this.floatingLabelProgress,
required this.floatingLabelAlignment,
- this.border,
- this.borderGap,
+ required this.border,
+ required this.borderGap,
required this.alignLabelWithHint,
required this.isDense,
- this.visualDensity,
+ required this.visualDensity,
this.icon,
this.input,
this.label,
@@ -594,11 +594,11 @@
final double floatingLabelHeight;
final double floatingLabelProgress;
final FloatingLabelAlignment floatingLabelAlignment;
- final InputBorder? border;
- final _InputBorderGap? borderGap;
+ final InputBorder border;
+ final _InputBorderGap borderGap;
final bool alignLabelWithHint;
final bool? isDense;
- final VisualDensity? visualDensity;
+ final VisualDensity visualDensity;
final Widget? icon;
final Widget? input;
final Widget? label;
@@ -788,14 +788,14 @@
TextAlignVertical get _defaultTextAlignVertical => _isOutlineAligned
? TextAlignVertical.center
: TextAlignVertical.top;
- TextAlignVertical? get textAlignVertical => _textAlignVertical ?? _defaultTextAlignVertical;
+ TextAlignVertical get textAlignVertical => _textAlignVertical ?? _defaultTextAlignVertical;
TextAlignVertical? _textAlignVertical;
set textAlignVertical(TextAlignVertical? value) {
if (_textAlignVertical == value) {
return;
}
// No need to relayout if the effective value is still the same.
- if (textAlignVertical!.y == (value?.y ?? _defaultTextAlignVertical.y)) {
+ if (textAlignVertical.y == (value?.y ?? _defaultTextAlignVertical.y)) {
_textAlignVertical = value;
return;
}
@@ -828,7 +828,7 @@
// Indicates that the decoration should be aligned to accommodate an outline
// border.
bool get _isOutlineAligned {
- return !decoration.isCollapsed && decoration.border!.isOutline;
+ return !decoration.isCollapsed && decoration.border.isOutline;
}
@override
@@ -970,7 +970,7 @@
// Increase the available width for the label when it is scaled down.
final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress)!;
double suffixIconWidth = _boxSize(suffixIcon).width;
- if (decoration.border!.isOutline) {
+ if (decoration.border.isOutline) {
suffixIconWidth = lerpDouble(suffixIconWidth, 0.0, decoration.floatingLabelProgress)!;
}
final double labelWidth = math.max(
@@ -1006,7 +1006,7 @@
final double labelHeight = label == null
? 0
: decoration.floatingLabelHeight;
- final double topHeight = decoration.border!.isOutline
+ final double topHeight = decoration.border.isOutline
? math.max(labelHeight - boxToBaseline[label]!, 0)
: labelHeight;
final double counterHeight = counter == null
@@ -1021,7 +1021,7 @@
counterHeight,
helperErrorHeight,
);
- final Offset densityOffset = decoration.visualDensity!.baseSizeAdjustment;
+ final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment;
boxToBaseline[input] = _layoutLineBox(
input,
boxConstraints.deflate(EdgeInsets.only(
@@ -1034,8 +1034,8 @@
);
// The field can be occupied by a hint or by the input itself
- final double hintHeight = hint == null ? 0 : hint!.size.height;
- final double inputDirectHeight = input == null ? 0 : input!.size.height;
+ final double hintHeight = hint?.size.height ?? 0;
+ final double inputDirectHeight = input?.size.height ?? 0;
final double inputHeight = math.max(hintHeight, inputDirectHeight);
final double inputInternalBaseline = math.max(
boxToBaseline[input]!,
@@ -1064,8 +1064,8 @@
);
// Calculate the height of the input text container.
- final double prefixIconHeight = prefixIcon == null ? 0 : prefixIcon!.size.height;
- final double suffixIconHeight = suffixIcon == null ? 0 : suffixIcon!.size.height;
+ final double prefixIconHeight = prefixIcon?.size.height ?? 0;
+ final double suffixIconHeight = suffixIcon?.size.height ?? 0;
final double fixIconHeight = math.max(prefixIconHeight, suffixIconHeight);
final double contentHeight = math.max(
fixIconHeight,
@@ -1097,7 +1097,7 @@
final double overflow = math.max(0, contentHeight - maxContainerHeight);
// Map textAlignVertical from -1:1 to 0:1 so that it can be used to scale
// the baseline from its minimum to maximum values.
- final double textAlignVerticalFactor = (textAlignVertical!.y + 1.0) / 2.0;
+ final double textAlignVerticalFactor = (textAlignVertical.y + 1.0) / 2.0;
// Adjust to try to fit top overflow inside the input on an inverse scale of
// textAlignVertical, so that top aligned text adjusts the most and bottom
// aligned text doesn't adjust at all.
@@ -1137,7 +1137,7 @@
outlineTopBaseline,
outlineCenterBaseline,
outlineBottomBaseline,
- textAlignVertical!,
+ textAlignVertical,
);
// Find the positions of the text below the input when it exists.
@@ -1276,7 +1276,7 @@
final double inputHeight = _lineHeight(availableInputWidth, <RenderBox?>[input, hint]);
final double inputMaxHeight = <double>[inputHeight, prefixHeight, suffixHeight].reduce(math.max);
- final Offset densityOffset = decoration.visualDensity!.baseSizeAdjustment;
+ final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment;
final double contentHeight = contentPadding.top
+ (label == null ? 0.0 : decoration.floatingLabelHeight)
+ inputMaxHeight
@@ -1337,15 +1337,15 @@
_boxParentData(container!).offset = Offset(x, 0.0);
}
- double? height;
+ late double height;
double centerLayout(RenderBox box, double x) {
- _boxParentData(box).offset = Offset(x, (height! - box.size.height) / 2.0);
+ _boxParentData(box).offset = Offset(x, (height - box.size.height) / 2.0);
return box.size.width;
}
- double? baseline;
+ late double baseline;
double baselineLayout(RenderBox box, double x) {
- _boxParentData(box).offset = Offset(x, baseline! - layout.boxToBaseline[box]!);
+ _boxParentData(box).offset = Offset(x, baseline - layout.boxToBaseline[box]!);
return box.size.width;
}
@@ -1468,7 +1468,7 @@
// _BorderContainer's x and is independent of label's x.
switch (textDirection) {
case TextDirection.rtl:
- decoration.borderGap!.start = lerpDouble(labelX + _boxSize(label).width,
+ decoration.borderGap.start = lerpDouble(labelX + _boxSize(label).width,
_boxSize(container).width / 2.0 + floatWidth / 2.0,
floatAlign);
@@ -1477,15 +1477,15 @@
// The value of _InputBorderGap.start is relative to the origin of the
// _BorderContainer which is inset by the icon's width. Although, when
// floating label is centered, it's already relative to _BorderContainer.
- decoration.borderGap!.start = lerpDouble(labelX - _boxSize(icon).width,
+ decoration.borderGap.start = lerpDouble(labelX - _boxSize(icon).width,
_boxSize(container).width / 2.0 - floatWidth / 2.0,
floatAlign);
break;
}
- decoration.borderGap!.extent = label!.size.width * _kFinalLabelScale;
+ decoration.borderGap.extent = label!.size.width * _kFinalLabelScale;
} else {
- decoration.borderGap!.start = null;
- decoration.borderGap!.extent = 0.0;
+ decoration.borderGap.start = null;
+ decoration.borderGap.extent = 0.0;
}
size = constraints.constrain(Size(overallWidth, overallHeight));
@@ -1513,11 +1513,11 @@
// +1 shifts the range of x from (-1.0, 1.0) to (0.0, 2.0).
final double floatAlign = decoration.floatingLabelAlignment._x + 1;
final double floatWidth = labelWidth * _kFinalLabelScale;
- final double borderWeight = decoration.border!.borderSide.width;
+ final double borderWeight = decoration.border.borderSide.width;
final double t = decoration.floatingLabelProgress;
// The center of the outline border label ends up a little below the
// center of the top border line.
- final bool isOutlineBorder = decoration.border != null && decoration.border!.isOutline;
+ final bool isOutlineBorder = decoration.border != null && decoration.border.isOutline;
// Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028
// Center the scaled label relative to the border.
final double floatingY = isOutlineBorder ? (-labelHeight * _kFinalLabelScale) / 2.0 + borderWeight / 2.0 : contentPadding.top;
@@ -1906,19 +1906,14 @@
}
InputDecoration? _effectiveDecoration;
- InputDecoration? get decoration {
- _effectiveDecoration ??= widget.decoration.applyDefaults(
- Theme.of(context).inputDecorationTheme,
- );
- return _effectiveDecoration;
- }
+ InputDecoration get decoration => _effectiveDecoration ??= widget.decoration.applyDefaults(Theme.of(context).inputDecorationTheme);
TextAlign? get textAlign => widget.textAlign;
bool get isFocused => widget.isFocused;
- bool get isHovering => widget.isHovering && decoration!.enabled;
+ bool get isHovering => widget.isHovering && decoration.enabled;
bool get isEmpty => widget.isEmpty;
bool get _floatingLabelEnabled {
- return decoration!.floatingLabelBehavior != FloatingLabelBehavior.never;
+ return decoration.floatingLabelBehavior != FloatingLabelBehavior.never;
}
@override
@@ -1939,7 +1934,7 @@
}
}
- final String? errorText = decoration!.errorText;
+ final String? errorText = decoration.errorText;
final String? oldErrorText = old.decoration.errorText;
if (_floatingLabelController.isCompleted && errorText != null && errorText != oldErrorText) {
@@ -1960,23 +1955,23 @@
if (isFocused) {
return themeData.colorScheme.primary;
}
- if (decoration!.filled!) {
+ if (decoration.filled!) {
return themeData.hintColor;
}
final Color enabledColor = themeData.colorScheme.onSurface.withOpacity(0.38);
if (isHovering) {
- final Color hoverColor = decoration!.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
+ final Color hoverColor = decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
return Color.alphaBlend(hoverColor.withOpacity(0.12), enabledColor);
}
return enabledColor;
}
Color _getFillColor(ThemeData themeData) {
- if (decoration!.filled != true) { // filled == null same as filled == false
+ if (decoration.filled != true) { // filled == null same as filled == false
return Colors.transparent;
}
- if (decoration!.fillColor != null) {
- return MaterialStateProperty.resolveAs(decoration!.fillColor!, materialState);
+ if (decoration.fillColor != null) {
+ return MaterialStateProperty.resolveAs(decoration.fillColor!, materialState);
}
// dark theme: 10% white (enabled), 5% white (disabled)
@@ -1988,17 +1983,17 @@
switch (themeData.brightness) {
case Brightness.dark:
- return decoration!.enabled ? darkEnabled : darkDisabled;
+ return decoration.enabled ? darkEnabled : darkDisabled;
case Brightness.light:
- return decoration!.enabled ? lightEnabled : lightDisabled;
+ return decoration.enabled ? lightEnabled : lightDisabled;
}
}
Color _getHoverColor(ThemeData themeData) {
- if (decoration!.filled == null || !decoration!.filled! || isFocused || !decoration!.enabled) {
+ if (decoration.filled == null || !decoration.filled! || isFocused || !decoration.enabled) {
return Colors.transparent;
}
- return decoration!.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
+ return decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
}
Color _getIconColor(ThemeData themeData) {
@@ -2038,8 +2033,8 @@
// hint would.
bool get _hasInlineLabel {
return !widget._labelShouldWithdraw
- && (decoration!.labelText != null || decoration!.label != null)
- && decoration!.floatingLabelBehavior != FloatingLabelBehavior.always;
+ && (decoration.labelText != null || decoration.label != null)
+ && decoration.floatingLabelBehavior != FloatingLabelBehavior.always;
}
// If the label is a floating placeholder, it's always shown.
@@ -2049,10 +2044,10 @@
// i.e. when they appear in place of the empty text field.
TextStyle _getInlineLabelStyle(ThemeData themeData) {
final TextStyle defaultStyle = TextStyle(
- color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor,
+ color: decoration.enabled ? themeData.hintColor : themeData.disabledColor,
);
- final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.labelStyle, materialState)
+ final TextStyle? style = MaterialStateProperty.resolveAs(decoration.labelStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState);
return themeData.textTheme.subtitle1!
@@ -2066,10 +2061,10 @@
// i.e. when they appear in place of the empty text field.
TextStyle _getInlineHintStyle(ThemeData themeData) {
final TextStyle defaultStyle = TextStyle(
- color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor,
+ color: decoration.enabled ? themeData.hintColor : themeData.disabledColor,
);
- final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.hintStyle, materialState)
+ final TextStyle? style = MaterialStateProperty.resolveAs(decoration.hintStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.hintStyle, materialState);
return themeData.textTheme.subtitle1!
@@ -2080,15 +2075,15 @@
TextStyle _getFloatingLabelStyle(ThemeData themeData) {
TextStyle getFallbackTextStyle() {
- final Color color = decoration!.errorText != null
- ? decoration!.errorStyle?.color ?? themeData.errorColor
+ final Color color = decoration.errorText != null
+ ? decoration.errorStyle?.color ?? themeData.errorColor
: _getActiveColor(themeData);
- return TextStyle(color: decoration!.enabled ? color : themeData.disabledColor)
- .merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle);
+ return TextStyle(color: decoration.enabled ? color : themeData.disabledColor)
+ .merge(decoration.floatingLabelStyle ?? decoration.labelStyle);
}
- final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.floatingLabelStyle, materialState)
+ final TextStyle? style = MaterialStateProperty.resolveAs(decoration.floatingLabelStyle, materialState)
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.floatingLabelStyle, materialState);
return themeData.textTheme.subtitle1!
@@ -2099,29 +2094,29 @@
}
TextStyle _getHelperStyle(ThemeData themeData) {
- final Color color = decoration!.enabled ? themeData.hintColor : Colors.transparent;
- return themeData.textTheme.caption!.copyWith(color: color).merge(MaterialStateProperty.resolveAs(decoration!.helperStyle, materialState));
+ final Color color = decoration.enabled ? themeData.hintColor : Colors.transparent;
+ return themeData.textTheme.caption!.copyWith(color: color).merge(MaterialStateProperty.resolveAs(decoration.helperStyle, materialState));
}
TextStyle _getErrorStyle(ThemeData themeData) {
- final Color color = decoration!.enabled ? themeData.errorColor : Colors.transparent;
- return themeData.textTheme.caption!.copyWith(color: color).merge(decoration!.errorStyle);
+ final Color color = decoration.enabled ? themeData.errorColor : Colors.transparent;
+ return themeData.textTheme.caption!.copyWith(color: color).merge(decoration.errorStyle);
}
Set<MaterialState> get materialState {
return <MaterialState>{
- if (!decoration!.enabled) MaterialState.disabled,
+ if (!decoration.enabled) MaterialState.disabled,
if (isFocused) MaterialState.focused,
if (isHovering) MaterialState.hovered,
- if (decoration!.errorText != null) MaterialState.error,
+ if (decoration.errorText != null) MaterialState.error,
};
}
InputBorder _getDefaultBorder(ThemeData themeData) {
- final InputBorder border = MaterialStateProperty.resolveAs(decoration!.border, materialState)
+ final InputBorder border = MaterialStateProperty.resolveAs(decoration.border, materialState)
?? const UnderlineInputBorder();
- if (decoration!.border is MaterialStateProperty<InputBorder>) {
+ if (decoration.border is MaterialStateProperty<InputBorder>) {
return border;
}
@@ -2130,18 +2125,18 @@
}
final Color borderColor;
- if (decoration!.enabled || isFocused) {
- borderColor = decoration!.errorText == null
+ if (decoration.enabled || isFocused) {
+ borderColor = decoration.errorText == null
? _getDefaultBorderColor(themeData)
: themeData.errorColor;
} else {
- borderColor = ((decoration!.filled ?? false) && !(decoration!.border?.isOutline ?? false))
+ borderColor = ((decoration.filled ?? false) && !(decoration.border?.isOutline ?? false))
? Colors.transparent
: themeData.disabledColor;
}
final double borderWeight;
- if (decoration!.isCollapsed || decoration?.border == InputBorder.none || !decoration!.enabled) {
+ if (decoration.isCollapsed || decoration.border == InputBorder.none || !decoration.enabled) {
borderWeight = 0.0;
} else {
borderWeight = isFocused ? 2.0 : 1.0;
@@ -2157,29 +2152,30 @@
final TextBaseline textBaseline = labelStyle.textBaseline!;
final TextStyle hintStyle = _getInlineHintStyle(themeData);
- final Widget? hint = decoration!.hintText == null ? null : AnimatedOpacity(
+ final String? hintText = decoration.hintText;
+ final Widget? hint = hintText == null ? null : AnimatedOpacity(
opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0,
duration: _kTransitionDuration,
curve: _kTransitionCurve,
alwaysIncludeSemantics: true,
child: Text(
- decoration!.hintText!,
+ hintText,
style: hintStyle,
- textDirection: decoration!.hintTextDirection,
+ textDirection: decoration.hintTextDirection,
overflow: TextOverflow.ellipsis,
textAlign: textAlign,
- maxLines: decoration!.hintMaxLines,
+ maxLines: decoration.hintMaxLines,
),
);
- final bool isError = decoration!.errorText != null;
+ final bool isError = decoration.errorText != null;
InputBorder? border;
- if (!decoration!.enabled) {
- border = isError ? decoration!.errorBorder : decoration!.disabledBorder;
+ if (!decoration.enabled) {
+ border = isError ? decoration.errorBorder : decoration.disabledBorder;
} else if (isFocused) {
- border = isError ? decoration!.focusedErrorBorder : decoration!.focusedBorder;
+ border = isError ? decoration.focusedErrorBorder : decoration.focusedBorder;
} else {
- border = isError ? decoration!.errorBorder : decoration!.enabledBorder;
+ border = isError ? decoration.errorBorder : decoration.enabledBorder;
}
border ??= _getDefaultBorder(themeData);
@@ -2192,7 +2188,7 @@
isHovering: isHovering,
);
- final Widget? label = decoration!.labelText == null && decoration!.label == null ? null : _Shaker(
+ final Widget? label = decoration.labelText == null && decoration.label == null ? null : _Shaker(
animation: _shakingLabelController.view,
child: AnimatedOpacity(
duration: _kTransitionDuration,
@@ -2204,8 +2200,8 @@
style: widget._labelShouldWithdraw
? _getFloatingLabelStyle(themeData)
: labelStyle,
- child: decoration!.label ?? Text(
- decoration!.labelText!,
+ child: decoration.label ?? Text(
+ decoration.labelText!,
overflow: TextOverflow.ellipsis,
textAlign: textAlign,
),
@@ -2213,27 +2209,27 @@
),
);
- final Widget? prefix = decoration!.prefix == null && decoration!.prefixText == null ? null :
+ final Widget? prefix = decoration.prefix == null && decoration.prefixText == null ? null :
_AffixText(
labelIsFloating: widget._labelShouldWithdraw,
- text: decoration!.prefixText,
- style: MaterialStateProperty.resolveAs(decoration!.prefixStyle, materialState) ?? hintStyle,
- child: decoration!.prefix,
+ text: decoration.prefixText,
+ style: MaterialStateProperty.resolveAs(decoration.prefixStyle, materialState) ?? hintStyle,
+ child: decoration.prefix,
);
- final Widget? suffix = decoration!.suffix == null && decoration!.suffixText == null ? null :
+ final Widget? suffix = decoration.suffix == null && decoration.suffixText == null ? null :
_AffixText(
labelIsFloating: widget._labelShouldWithdraw,
- text: decoration!.suffixText,
- style: MaterialStateProperty.resolveAs(decoration!.suffixStyle, materialState) ?? hintStyle,
- child: decoration!.suffix,
+ text: decoration.suffixText,
+ style: MaterialStateProperty.resolveAs(decoration.suffixStyle, materialState) ?? hintStyle,
+ child: decoration.suffix,
);
- final bool decorationIsDense = decoration!.isDense ?? false;
+ final bool decorationIsDense = decoration.isDense ?? false;
final double iconSize = decorationIsDense ? 18.0 : 24.0;
- final Widget? icon = decoration!.icon == null ? null :
+ final Widget? icon = decoration.icon == null ? null :
Padding(
padding: const EdgeInsetsDirectional.only(end: 16.0),
child: IconTheme.merge(
@@ -2241,16 +2237,16 @@
color: _getIconColor(themeData),
size: iconSize,
),
- child: decoration!.icon!,
+ child: decoration.icon!,
),
);
- final Widget? prefixIcon = decoration!.prefixIcon == null ? null :
+ final Widget? prefixIcon = decoration.prefixIcon == null ? null :
Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: ConstrainedBox(
- constraints: decoration!.prefixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
+ constraints: decoration.prefixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
const BoxConstraints(
minWidth: kMinInteractiveDimension,
minHeight: kMinInteractiveDimension,
@@ -2261,17 +2257,17 @@
color: _getPrefixIconColor(themeData),
size: iconSize,
),
- child: decoration!.prefixIcon!,
+ child: decoration.prefixIcon!,
),
),
);
- final Widget? suffixIcon = decoration!.suffixIcon == null ? null :
+ final Widget? suffixIcon = decoration.suffixIcon == null ? null :
Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: ConstrainedBox(
- constraints: decoration!.suffixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
+ constraints: decoration.suffixIconConstraints ?? themeData.visualDensity.effectiveConstraints(
const BoxConstraints(
minWidth: kMinInteractiveDimension,
minHeight: kMinInteractiveDimension,
@@ -2282,33 +2278,33 @@
color: _getSuffixIconColor(themeData),
size: iconSize,
),
- child: decoration!.suffixIcon!,
+ child: decoration.suffixIcon!,
),
),
);
final Widget helperError = _HelperError(
textAlign: textAlign,
- helperText: decoration!.helperText,
+ helperText: decoration.helperText,
helperStyle: _getHelperStyle(themeData),
- helperMaxLines: decoration!.helperMaxLines,
- errorText: decoration!.errorText,
+ helperMaxLines: decoration.helperMaxLines,
+ errorText: decoration.errorText,
errorStyle: _getErrorStyle(themeData),
- errorMaxLines: decoration!.errorMaxLines,
+ errorMaxLines: decoration.errorMaxLines,
);
Widget? counter;
- if (decoration!.counter != null) {
- counter = decoration!.counter;
- } else if (decoration!.counterText != null && decoration!.counterText != '') {
+ if (decoration.counter != null) {
+ counter = decoration.counter;
+ } else if (decoration.counterText != null && decoration.counterText != '') {
counter = Semantics(
container: true,
liveRegion: isFocused,
child: Text(
- decoration!.counterText!,
- style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration!.counterStyle, materialState)),
+ decoration.counterText!,
+ style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration.counterStyle, materialState)),
overflow: TextOverflow.ellipsis,
- semanticsLabel: decoration!.semanticCounterText,
+ semanticsLabel: decoration.semanticCounterText,
),
);
}
@@ -2316,17 +2312,17 @@
// The _Decoration widget and _RenderDecoration assume that contentPadding
// has been resolved to EdgeInsets.
final TextDirection textDirection = Directionality.of(context);
- final EdgeInsets? decorationContentPadding = decoration!.contentPadding?.resolve(textDirection);
+ final EdgeInsets? decorationContentPadding = decoration.contentPadding?.resolve(textDirection);
final EdgeInsets contentPadding;
final double floatingLabelHeight;
- if (decoration!.isCollapsed) {
+ if (decoration.isCollapsed) {
floatingLabelHeight = 0.0;
contentPadding = decorationContentPadding ?? EdgeInsets.zero;
} else if (!border.isOutline) {
// 4.0: the vertical gap between the inline elements and the floating label.
floatingLabelHeight = (4.0 + 0.75 * labelStyle.fontSize!) * MediaQuery.textScaleFactorOf(context);
- if (decoration!.filled ?? false) {
+ if (decoration.filled ?? false) {
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
@@ -2348,14 +2344,14 @@
final _Decorator decorator = _Decorator(
decoration: _Decoration(
contentPadding: contentPadding,
- isCollapsed: decoration!.isCollapsed,
+ isCollapsed: decoration.isCollapsed,
floatingLabelHeight: floatingLabelHeight,
- floatingLabelAlignment: decoration!.floatingLabelAlignment!,
+ floatingLabelAlignment: decoration.floatingLabelAlignment!,
floatingLabelProgress: _floatingLabelController.value,
border: border,
borderGap: _borderGap,
- alignLabelWithHint: decoration!.alignLabelWithHint ?? false,
- isDense: decoration!.isDense,
+ alignLabelWithHint: decoration.alignLabelWithHint ?? false,
+ isDense: decoration.isDense,
visualDensity: themeData.visualDensity,
icon: icon,
input: widget.child,
@@ -2376,7 +2372,7 @@
expands: widget.expands,
);
- final BoxConstraints? constraints = decoration!.constraints ?? themeData.inputDecorationTheme.constraints;
+ final BoxConstraints? constraints = decoration.constraints ?? themeData.inputDecorationTheme.constraints;
if (constraints != null) {
return ConstrainedBox(
constraints: constraints,
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index dc1cb33..98e586b 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -2152,7 +2152,7 @@
@override
void performPrivateCommand(String action, Map<String, dynamic> data) {
- widget.onAppPrivateCommand!(action, data);
+ widget.onAppPrivateCommand?.call(action, data);
}
// The original position of the caret on FloatingCursorDragState.start.
diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart
index 55acff9..569c0f6 100644
--- a/packages/flutter/test/widgets/editable_text_test.dart
+++ b/packages/flutter/test/widgets/editable_text_test.dart
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:convert' show jsonDecode;
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
@@ -397,6 +398,53 @@
);
});
+ testWidgets('onAppPrivateCommand does not throw', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(),
+ child: Directionality(
+ textDirection: TextDirection.ltr,
+ child: FocusScope(
+ node: focusScopeNode,
+ autofocus: true,
+ child: EditableText(
+ backgroundCursorColor: Colors.grey,
+ controller: controller,
+ focusNode: focusNode,
+ style: textStyle,
+ cursorColor: cursorColor,
+ ),
+ ),
+ ),
+ ),
+ );
+
+ await tester.tap(find.byType(EditableText));
+ await tester.showKeyboard(find.byType(EditableText));
+ controller.text = 'test';
+ await tester.idle();
+
+ final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
+ 'args': <dynamic>[
+ -1, // The magic clint id that points to the current client.
+ jsonDecode('{"action": "actionCommand", "data": {"input_context" : "abcdefg"}}'),
+ ],
+ 'method': 'TextInputClient.performPrivateCommand',
+ });
+
+ Object? error;
+ try {
+ await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
+ 'flutter/textinput',
+ messageBytes,
+ (ByteData? _) {},
+ );
+ } catch (e) {
+ error = e;
+ }
+ expect(error, isNull);
+ });
+
group('Infer keyboardType from autofillHints', () {
testWidgets(
'infer keyboard types from autofillHints: ios',