mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
This reverts commit 1c374c6598
.
This commit is contained in:
parent
6c10f19b80
commit
7d9f7b4ca1
@ -1,48 +0,0 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flutter code sample for InputDecoration
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: _title,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text(_title)),
|
||||
body: const MyStatelessWidget(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyStatelessWidget extends StatelessWidget {
|
||||
const MyStatelessWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextFormField(
|
||||
initialValue: 'abc',
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.person),
|
||||
prefixIconColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return Colors.green;
|
||||
} if (states.contains(MaterialState.error)) {
|
||||
return Colors.red;
|
||||
}
|
||||
return Colors.grey;
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flutter code sample for InputDecoration
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: _title,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text(_title)),
|
||||
body: const MyStatelessWidget(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyStatelessWidget extends StatelessWidget {
|
||||
const MyStatelessWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
return Theme(
|
||||
data: themeData.copyWith(
|
||||
inputDecorationTheme: themeData.inputDecorationTheme.copyWith(
|
||||
prefixIconColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return Colors.green;
|
||||
} if (states.contains(MaterialState.error)) {
|
||||
return Colors.red;
|
||||
}
|
||||
return Colors.grey;
|
||||
}),
|
||||
)
|
||||
),
|
||||
child: TextFormField(
|
||||
initialValue: 'abc',
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: Icon(Icons.person),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ import 'package:flutter/widgets.dart';
|
||||
import 'colors.dart';
|
||||
import 'constants.dart';
|
||||
import 'input_border.dart';
|
||||
import 'material_state.dart';
|
||||
import 'theme.dart';
|
||||
import 'theme_data.dart';
|
||||
|
||||
@ -2082,7 +2081,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
if (decoration!.filled != true) // filled == null same as filled == false
|
||||
return Colors.transparent;
|
||||
if (decoration!.fillColor != null)
|
||||
return MaterialStateProperty.resolveAs(decoration!.fillColor!, materialState);
|
||||
return decoration!.fillColor!;
|
||||
|
||||
// dark theme: 10% white (enabled), 5% white (disabled)
|
||||
// light theme: 4% black (enabled), 2% black (disabled)
|
||||
@ -2105,33 +2104,16 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
return decoration!.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor;
|
||||
}
|
||||
|
||||
Color _getIconColor(ThemeData themeData) {
|
||||
Color _resolveIconColor(Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled) && !states.contains(MaterialState.focused))
|
||||
return themeData.disabledColor;
|
||||
Color _getDefaultIconColor(ThemeData themeData) {
|
||||
if (!decoration!.enabled && !isFocused)
|
||||
return themeData.disabledColor;
|
||||
|
||||
if (states.contains(MaterialState.focused))
|
||||
return themeData.colorScheme.primary;
|
||||
|
||||
switch (themeData.brightness) {
|
||||
case Brightness.dark:
|
||||
return Colors.white70;
|
||||
case Brightness.light:
|
||||
return Colors.black45;
|
||||
}
|
||||
switch (themeData.brightness) {
|
||||
case Brightness.dark:
|
||||
return Colors.white70;
|
||||
case Brightness.light:
|
||||
return Colors.black45;
|
||||
}
|
||||
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.iconColor, materialState)
|
||||
?? MaterialStateProperty.resolveWith(_resolveIconColor).resolve(materialState);
|
||||
}
|
||||
|
||||
Color _getPrefixIconColor(ThemeData themeData) {
|
||||
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.prefixIconColor, materialState)
|
||||
?? _getIconColor(themeData);
|
||||
}
|
||||
|
||||
Color _getSuffixIconColor(ThemeData themeData) {
|
||||
return MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.suffixIconColor, materialState)
|
||||
?? _getIconColor(themeData);
|
||||
}
|
||||
|
||||
// True if the label will be shown and the hint will not.
|
||||
@ -2150,45 +2132,31 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
// The base style for the inline label or hint when they're displayed "inline",
|
||||
// i.e. when they appear in place of the empty text field.
|
||||
TextStyle _getInlineStyle(ThemeData themeData) {
|
||||
final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.labelStyle, materialState)
|
||||
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState);
|
||||
|
||||
if (style == null) {
|
||||
return themeData.textTheme.subtitle1!.merge(widget.baseStyle)
|
||||
.copyWith(color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor);
|
||||
}
|
||||
|
||||
return themeData.textTheme.subtitle1!.merge(style.merge(widget.baseStyle));
|
||||
return themeData.textTheme.subtitle1!.merge(widget.baseStyle)
|
||||
.copyWith(color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor);
|
||||
}
|
||||
|
||||
TextStyle _getFloatingLabelStyle(ThemeData themeData) {
|
||||
final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.floatingLabelStyle, materialState)
|
||||
?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.floatingLabelStyle, materialState);
|
||||
final Color color = decoration!.errorText != null
|
||||
? decoration!.errorStyle?.color ?? themeData.errorColor
|
||||
: _getActiveColor(themeData);
|
||||
final TextStyle style = themeData.textTheme.subtitle1!.merge(widget.baseStyle);
|
||||
// Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028
|
||||
// Setting TextStyle.height to 1 ensures that the label's height will equal
|
||||
// its font size.
|
||||
return themeData.fixTextFieldOutlineLabel
|
||||
? style
|
||||
.copyWith(height: 1, color: decoration!.enabled ? color : themeData.disabledColor)
|
||||
.merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle)
|
||||
: style
|
||||
.copyWith(color: decoration!.enabled ? color : themeData.disabledColor)
|
||||
.merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle);
|
||||
|
||||
if (style == null) {
|
||||
final Color color = decoration!.errorText != null
|
||||
? decoration!.errorStyle?.color ?? themeData.errorColor
|
||||
: _getActiveColor(themeData);
|
||||
final TextStyle style = themeData.textTheme.subtitle1!.merge(widget.baseStyle);
|
||||
// Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028
|
||||
// Setting TextStyle.height to 1 ensures that the label's height will equal
|
||||
// its font size.
|
||||
return themeData.fixTextFieldOutlineLabel
|
||||
? style
|
||||
.copyWith(height: 1, color: decoration!.enabled ? color : themeData.disabledColor)
|
||||
.merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle)
|
||||
: style
|
||||
.copyWith(color: decoration!.enabled ? color : themeData.disabledColor)
|
||||
.merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle);
|
||||
}
|
||||
return style
|
||||
.copyWith(height: themeData.fixTextFieldOutlineLabel ? 1 : null)
|
||||
.merge(widget.baseStyle);
|
||||
}
|
||||
|
||||
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));
|
||||
return themeData.textTheme.caption!.copyWith(color: color).merge(decoration!.helperStyle);
|
||||
}
|
||||
|
||||
TextStyle _getErrorStyle(ThemeData themeData) {
|
||||
@ -2196,25 +2164,9 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
return themeData.textTheme.caption!.copyWith(color: color).merge(decoration!.errorStyle);
|
||||
}
|
||||
|
||||
Set<MaterialState> get materialState {
|
||||
return <MaterialState>{
|
||||
if (!decoration!.enabled) MaterialState.disabled,
|
||||
if (isFocused) MaterialState.focused,
|
||||
if (isHovering) MaterialState.hovered,
|
||||
if (decoration!.errorText != null) MaterialState.error,
|
||||
};
|
||||
}
|
||||
|
||||
InputBorder _getDefaultBorder(ThemeData themeData) {
|
||||
final InputBorder border = MaterialStateProperty.resolveAs(decoration!.border, materialState)
|
||||
?? const UnderlineInputBorder();
|
||||
|
||||
if (decoration!.border is MaterialStateProperty<InputBorder>) {
|
||||
return border;
|
||||
}
|
||||
|
||||
if (border.borderSide == BorderSide.none) {
|
||||
return border;
|
||||
if (decoration!.border?.borderSide == BorderSide.none) {
|
||||
return decoration!.border!;
|
||||
}
|
||||
|
||||
final Color borderColor;
|
||||
@ -2234,6 +2186,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
else
|
||||
borderWeight = isFocused ? 2.0 : 1.0;
|
||||
|
||||
final InputBorder border = decoration!.border ?? const UnderlineInputBorder();
|
||||
return border.copyWith(borderSide: BorderSide(color: borderColor, width: borderWeight));
|
||||
}
|
||||
|
||||
@ -2243,7 +2196,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
final TextStyle inlineStyle = _getInlineStyle(themeData);
|
||||
final TextBaseline textBaseline = inlineStyle.textBaseline!;
|
||||
|
||||
final TextStyle hintStyle = inlineStyle.merge(MaterialStateProperty.resolveAs(decoration!.hintStyle, materialState));
|
||||
final TextStyle hintStyle = inlineStyle.merge(decoration!.hintStyle);
|
||||
final Widget? hint = decoration!.hintText == null ? null : AnimatedOpacity(
|
||||
opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0,
|
||||
duration: _kTransitionDuration,
|
||||
@ -2282,8 +2235,8 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
// Setting TextStyle.height to 1 ensures that the label's height will equal
|
||||
// its font size.
|
||||
final TextStyle inlineLabelStyle = themeData.fixTextFieldOutlineLabel
|
||||
? inlineStyle.merge(MaterialStateProperty.resolveAs(decoration!.labelStyle, materialState)).copyWith(height: 1)
|
||||
: inlineStyle.merge(MaterialStateProperty.resolveAs(decoration!.labelStyle, materialState));
|
||||
? inlineStyle.merge(decoration!.labelStyle).copyWith(height: 1)
|
||||
: inlineStyle.merge(decoration!.labelStyle);
|
||||
final Widget? label = decoration!.labelText == null && decoration!.label == null ? null : _Shaker(
|
||||
animation: _shakingLabelController.view,
|
||||
child: AnimatedOpacity(
|
||||
@ -2309,7 +2262,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
_AffixText(
|
||||
labelIsFloating: widget._labelShouldWithdraw,
|
||||
text: decoration!.prefixText,
|
||||
style: MaterialStateProperty.resolveAs(decoration!.prefixStyle, materialState) ?? hintStyle,
|
||||
style: decoration!.prefixStyle ?? hintStyle,
|
||||
child: decoration!.prefix,
|
||||
);
|
||||
|
||||
@ -2317,20 +2270,21 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
_AffixText(
|
||||
labelIsFloating: widget._labelShouldWithdraw,
|
||||
text: decoration!.suffixText,
|
||||
style: MaterialStateProperty.resolveAs(decoration!.suffixStyle, materialState) ?? hintStyle,
|
||||
style: decoration!.suffixStyle ?? hintStyle,
|
||||
child: decoration!.suffix,
|
||||
);
|
||||
|
||||
|
||||
final Color activeColor = _getActiveColor(themeData);
|
||||
final bool decorationIsDense = decoration!.isDense == true; // isDense == null, same as false
|
||||
final double iconSize = decorationIsDense ? 18.0 : 24.0;
|
||||
final Color iconColor = isFocused ? activeColor : _getDefaultIconColor(themeData);
|
||||
|
||||
final Widget? icon = decoration!.icon == null ? null :
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(end: 16.0),
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(
|
||||
color: _getIconColor(themeData),
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
),
|
||||
child: decoration!.icon!,
|
||||
@ -2350,7 +2304,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
),
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(
|
||||
color: _getPrefixIconColor(themeData),
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
),
|
||||
child: decoration!.prefixIcon!,
|
||||
@ -2371,7 +2325,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
),
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(
|
||||
color: _getSuffixIconColor(themeData),
|
||||
color: iconColor,
|
||||
size: iconSize,
|
||||
),
|
||||
child: decoration!.suffixIcon!,
|
||||
@ -2398,7 +2352,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
liveRegion: isFocused,
|
||||
child: Text(
|
||||
decoration!.counterText!,
|
||||
style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration!.counterStyle, materialState)),
|
||||
style: _getHelperStyle(themeData).merge(decoration!.counterStyle),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
semanticsLabel: decoration!.semanticCounterText,
|
||||
),
|
||||
@ -2528,22 +2482,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
/// ** See code in examples/api/lib/material/input_decorator/input_decoration.3.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool dartpad --template=stateless_widget_scaffold}
|
||||
/// This sample shows how to style a `TextField` with a prefixIcon that changes color
|
||||
/// based on the `MaterialState`. The color defaults to gray, be blue while focused
|
||||
/// and red if in an error state.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/input_decorator/input_decoration.material_state.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool dartpad --template=stateless_widget_scaffold}
|
||||
/// This sample shows how to style a `TextField` with a prefixIcon that changes color
|
||||
/// based on the `MaterialState` through the use of `ThemeData`. The color defaults
|
||||
/// to gray, be blue while focused and red if in an error state.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/input_decorator/input_decoration.material_state.1.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [TextField], which is a text input widget that uses an
|
||||
@ -2569,7 +2507,6 @@ class InputDecoration {
|
||||
/// Similarly, only one of [suffix] and [suffixText] can be specified.
|
||||
const InputDecoration({
|
||||
this.icon,
|
||||
this.iconColor,
|
||||
this.label,
|
||||
this.labelText,
|
||||
this.labelStyle,
|
||||
@ -2593,12 +2530,10 @@ class InputDecoration {
|
||||
this.prefix,
|
||||
this.prefixText,
|
||||
this.prefixStyle,
|
||||
this.prefixIconColor,
|
||||
this.suffixIcon,
|
||||
this.suffix,
|
||||
this.suffixText,
|
||||
this.suffixStyle,
|
||||
this.suffixIconColor,
|
||||
this.suffixIconConstraints,
|
||||
this.counter,
|
||||
this.counterText,
|
||||
@ -2640,7 +2575,6 @@ class InputDecoration {
|
||||
this.enabled = true,
|
||||
}) : assert(enabled != null),
|
||||
icon = null,
|
||||
iconColor = null,
|
||||
label = null,
|
||||
labelText = null,
|
||||
labelStyle = null,
|
||||
@ -2659,13 +2593,11 @@ class InputDecoration {
|
||||
prefix = null,
|
||||
prefixText = null,
|
||||
prefixStyle = null,
|
||||
prefixIconColor = null,
|
||||
prefixIconConstraints = null,
|
||||
suffix = null,
|
||||
suffixIcon = null,
|
||||
suffixText = null,
|
||||
suffixStyle = null,
|
||||
suffixIconColor = null,
|
||||
suffixIconConstraints = null,
|
||||
counter = null,
|
||||
counterText = null,
|
||||
@ -2696,13 +2628,6 @@ class InputDecoration {
|
||||
/// See [Icon], [ImageIcon].
|
||||
final Widget? icon;
|
||||
|
||||
/// The color of the [icon].
|
||||
///
|
||||
/// If [iconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
final Color? iconColor;
|
||||
|
||||
/// Optional widget that describes the input field.
|
||||
///
|
||||
/// {@template flutter.material.inputDecoration.label}
|
||||
@ -2737,10 +2662,6 @@ class InputDecoration {
|
||||
/// The style to use for the [labelText] when the label is on top of the
|
||||
/// input field.
|
||||
///
|
||||
/// If [labelStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// When the [labelText] is above (i.e., vertically adjacent to) the input
|
||||
/// field, the text uses the [floatingLabelStyle] instead.
|
||||
///
|
||||
@ -2751,10 +2672,6 @@ class InputDecoration {
|
||||
/// The style to use for the [labelText] when the label is above (i.e.,
|
||||
/// vertically adjacent to) the input field.
|
||||
///
|
||||
/// If [floatingLabelStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to [labelStyle].
|
||||
final TextStyle? floatingLabelStyle;
|
||||
|
||||
@ -2767,10 +2684,6 @@ class InputDecoration {
|
||||
final String? helperText;
|
||||
|
||||
/// The style to use for the [helperText].
|
||||
///
|
||||
/// If [helperStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
final TextStyle? helperStyle;
|
||||
|
||||
/// The maximum number of lines the [helperText] can occupy.
|
||||
@ -2796,10 +2709,6 @@ class InputDecoration {
|
||||
|
||||
/// The style to use for the [hintText].
|
||||
///
|
||||
/// If [hintStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// Also used for the [labelText] when the [labelText] is displayed on
|
||||
/// top of the input field (i.e., at the same location on the screen where
|
||||
/// text may be entered in the [InputDecorator.child]).
|
||||
@ -2995,10 +2904,6 @@ class InputDecoration {
|
||||
|
||||
/// The style to use for the [prefixText].
|
||||
///
|
||||
/// If [prefixStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [hintStyle].
|
||||
///
|
||||
/// See also:
|
||||
@ -3006,15 +2911,6 @@ class InputDecoration {
|
||||
/// * [suffixStyle], the equivalent but on the trailing edge.
|
||||
final TextStyle? prefixStyle;
|
||||
|
||||
/// Optional color of the prefixIcon
|
||||
///
|
||||
/// Defaults to [iconColor]
|
||||
///
|
||||
/// If [prefixIconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
final Color? prefixIconColor;
|
||||
|
||||
/// An icon that appears after the editable part of the text field and
|
||||
/// after the [suffix] or [suffixText], within the decoration's container.
|
||||
///
|
||||
@ -3081,10 +2977,6 @@ class InputDecoration {
|
||||
|
||||
/// The style to use for the [suffixText].
|
||||
///
|
||||
/// If [suffixStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [hintStyle].
|
||||
///
|
||||
/// See also:
|
||||
@ -3092,15 +2984,6 @@ class InputDecoration {
|
||||
/// * [prefixStyle], the equivalent but on the leading edge.
|
||||
final TextStyle? suffixStyle;
|
||||
|
||||
/// Optional color of the suffixIcon
|
||||
///
|
||||
/// Defaults to [iconColor]
|
||||
///
|
||||
/// If [suffixIconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
final Color? suffixIconColor;
|
||||
|
||||
/// The constraints for the suffix icon.
|
||||
///
|
||||
/// This can be used to modify the [BoxConstraints] surrounding [suffixIcon].
|
||||
@ -3145,10 +3028,6 @@ class InputDecoration {
|
||||
|
||||
/// The style to use for the [counterText].
|
||||
///
|
||||
/// If [counterStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [helperStyle].
|
||||
final TextStyle? counterStyle;
|
||||
|
||||
@ -3325,15 +3204,11 @@ class InputDecoration {
|
||||
|
||||
/// The shape of the border to draw around the decoration's container.
|
||||
///
|
||||
/// If [border] is a [MaterialStateUnderlineInputBorder]
|
||||
/// or [MaterialStateOutlineInputBorder], then the effective border can depend on
|
||||
/// the [MaterialState.focused] state, i.e. if the [TextField] is focused or not.
|
||||
///
|
||||
/// If [border] derives from [InputBorder] the border's [InputBorder.borderSide],
|
||||
/// i.e. the border's color and width, will be overridden to reflect the input
|
||||
/// decorator's state. Only the border's shape is used. If custom [BorderSide]
|
||||
/// values are desired for a given state, all four borders – [errorBorder],
|
||||
/// [focusedBorder], [enabledBorder], [disabledBorder] – must be set.
|
||||
/// This border's [InputBorder.borderSide], i.e. the border's color and width,
|
||||
/// will be overridden to reflect the input decorator's state. Only the
|
||||
/// border's shape is used. If custom [BorderSide] values are desired for
|
||||
/// a given state, all four borders – [errorBorder], [focusedBorder],
|
||||
/// [enabledBorder], [disabledBorder] – must be set.
|
||||
///
|
||||
/// The decoration's container is the area which is filled if [filled] is
|
||||
/// true and bordered per the [border]. It's the area adjacent to
|
||||
@ -3401,7 +3276,6 @@ class InputDecoration {
|
||||
/// by the new values.
|
||||
InputDecoration copyWith({
|
||||
Widget? icon,
|
||||
Color? iconColor,
|
||||
Widget? label,
|
||||
String? labelText,
|
||||
TextStyle? labelStyle,
|
||||
@ -3425,12 +3299,10 @@ class InputDecoration {
|
||||
String? prefixText,
|
||||
BoxConstraints? prefixIconConstraints,
|
||||
TextStyle? prefixStyle,
|
||||
Color? prefixIconColor,
|
||||
Widget? suffixIcon,
|
||||
Widget? suffix,
|
||||
String? suffixText,
|
||||
TextStyle? suffixStyle,
|
||||
Color? suffixIconColor,
|
||||
BoxConstraints? suffixIconConstraints,
|
||||
Widget? counter,
|
||||
String? counterText,
|
||||
@ -3452,7 +3324,6 @@ class InputDecoration {
|
||||
}) {
|
||||
return InputDecoration(
|
||||
icon: icon ?? this.icon,
|
||||
iconColor: iconColor ?? this.iconColor,
|
||||
label: label ?? this.label,
|
||||
labelText: labelText ?? this.labelText,
|
||||
labelStyle: labelStyle ?? this.labelStyle,
|
||||
@ -3475,13 +3346,11 @@ class InputDecoration {
|
||||
prefix: prefix ?? this.prefix,
|
||||
prefixText: prefixText ?? this.prefixText,
|
||||
prefixStyle: prefixStyle ?? this.prefixStyle,
|
||||
prefixIconColor: prefixIconColor ?? this.prefixIconColor,
|
||||
prefixIconConstraints: prefixIconConstraints ?? this.prefixIconConstraints,
|
||||
suffixIcon: suffixIcon ?? this.suffixIcon,
|
||||
suffix: suffix ?? this.suffix,
|
||||
suffixText: suffixText ?? this.suffixText,
|
||||
suffixStyle: suffixStyle ?? this.suffixStyle,
|
||||
suffixIconColor: suffixIconColor ?? this.suffixIconColor,
|
||||
suffixIconConstraints: suffixIconConstraints ?? this.suffixIconConstraints,
|
||||
counter: counter ?? this.counter,
|
||||
counterText: counterText ?? this.counterText,
|
||||
@ -3547,7 +3416,6 @@ class InputDecoration {
|
||||
return false;
|
||||
return other is InputDecoration
|
||||
&& other.icon == icon
|
||||
&& other.iconColor == iconColor
|
||||
&& other.label == label
|
||||
&& other.labelText == labelText
|
||||
&& other.labelStyle == labelStyle
|
||||
@ -3567,13 +3435,11 @@ class InputDecoration {
|
||||
&& other.contentPadding == contentPadding
|
||||
&& other.isCollapsed == isCollapsed
|
||||
&& other.prefixIcon == prefixIcon
|
||||
&& other.prefixIconColor == prefixIconColor
|
||||
&& other.prefix == prefix
|
||||
&& other.prefixText == prefixText
|
||||
&& other.prefixStyle == prefixStyle
|
||||
&& other.prefixIconConstraints == prefixIconConstraints
|
||||
&& other.suffixIcon == suffixIcon
|
||||
&& other.suffixIconColor == suffixIconColor
|
||||
&& other.suffix == suffix
|
||||
&& other.suffixText == suffixText
|
||||
&& other.suffixStyle == suffixStyle
|
||||
@ -3601,7 +3467,6 @@ class InputDecoration {
|
||||
int get hashCode {
|
||||
final List<Object?> values = <Object?>[
|
||||
icon,
|
||||
iconColor,
|
||||
label,
|
||||
labelText,
|
||||
floatingLabelStyle,
|
||||
@ -3627,13 +3492,11 @@ class InputDecoration {
|
||||
border,
|
||||
enabled,
|
||||
prefixIcon,
|
||||
prefixIconColor,
|
||||
prefix,
|
||||
prefixText,
|
||||
prefixStyle,
|
||||
prefixIconConstraints,
|
||||
suffixIcon,
|
||||
suffixIconColor,
|
||||
suffix,
|
||||
suffixText,
|
||||
suffixStyle,
|
||||
@ -3659,7 +3522,6 @@ class InputDecoration {
|
||||
String toString() {
|
||||
final List<String> description = <String>[
|
||||
if (icon != null) 'icon: $icon',
|
||||
if (iconColor != null) 'iconColor: $iconColor',
|
||||
if (label != null) 'label: $label',
|
||||
if (labelText != null) 'labelText: "$labelText"',
|
||||
if (floatingLabelStyle != null) 'floatingLabelStyle: "$floatingLabelStyle"',
|
||||
@ -3675,13 +3537,11 @@ class InputDecoration {
|
||||
if (contentPadding != null) 'contentPadding: $contentPadding',
|
||||
if (isCollapsed) 'isCollapsed: $isCollapsed',
|
||||
if (prefixIcon != null) 'prefixIcon: $prefixIcon',
|
||||
if (prefixIconColor != null) 'prefixIconColor: $prefixIconColor',
|
||||
if (prefix != null) 'prefix: $prefix',
|
||||
if (prefixText != null) 'prefixText: $prefixText',
|
||||
if (prefixStyle != null) 'prefixStyle: $prefixStyle',
|
||||
if (prefixIconConstraints != null) 'prefixIconConstraints: $prefixIconConstraints',
|
||||
if (suffixIcon != null) 'suffixIcon: $suffixIcon',
|
||||
if (suffixIconColor != null) 'suffixIconColor: $suffixIconColor',
|
||||
if (suffix != null) 'suffix: $suffix',
|
||||
if (suffixText != null) 'suffixText: $suffixText',
|
||||
if (suffixStyle != null) 'suffixStyle: $suffixStyle',
|
||||
@ -3736,11 +3596,8 @@ class InputDecorationTheme with Diagnosticable {
|
||||
this.isDense = false,
|
||||
this.contentPadding,
|
||||
this.isCollapsed = false,
|
||||
this.iconColor,
|
||||
this.prefixStyle,
|
||||
this.prefixIconColor,
|
||||
this.suffixStyle,
|
||||
this.suffixIconColor,
|
||||
this.counterStyle,
|
||||
this.filled = false,
|
||||
this.fillColor,
|
||||
@ -3765,10 +3622,6 @@ class InputDecorationTheme with Diagnosticable {
|
||||
/// When the [InputDecoration.labelText] is floating above the input field,
|
||||
/// the text uses the [floatingLabelStyle] instead.
|
||||
///
|
||||
/// If [labelStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to a value derived from the base [TextStyle] for the
|
||||
/// input field and the current [Theme].
|
||||
final TextStyle? labelStyle;
|
||||
@ -3779,18 +3632,10 @@ class InputDecorationTheme with Diagnosticable {
|
||||
/// When the [InputDecoration.labelText] is on top of the input field, the
|
||||
/// text uses the [labelStyle] instead.
|
||||
///
|
||||
/// If [floatingLabelStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to [labelStyle].
|
||||
final TextStyle? floatingLabelStyle;
|
||||
|
||||
/// The style to use for [InputDecoration.helperText].
|
||||
///
|
||||
/// If [helperStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
final TextStyle? helperStyle;
|
||||
|
||||
/// The maximum number of lines the [InputDecoration.helperText] can occupy.
|
||||
@ -3808,10 +3653,6 @@ class InputDecorationTheme with Diagnosticable {
|
||||
|
||||
/// The style to use for the [InputDecoration.hintText].
|
||||
///
|
||||
/// If [hintStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// Also used for the [InputDecoration.labelText] when the
|
||||
/// [InputDecoration.labelText] is displayed on top of the input field (i.e.,
|
||||
/// at the same location on the screen where text may be entered in the input
|
||||
@ -3871,57 +3712,18 @@ class InputDecorationTheme with Diagnosticable {
|
||||
/// [InputDecoration.errorText], or an [InputDecoration.icon].
|
||||
final bool isCollapsed;
|
||||
|
||||
/// The Color to use for the [InputDecoration.icon].
|
||||
///
|
||||
/// If [iconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [ColorScheme.primary].
|
||||
final Color? iconColor;
|
||||
|
||||
/// The style to use for the [InputDecoration.prefixText].
|
||||
///
|
||||
/// If [prefixStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [hintStyle].
|
||||
final TextStyle? prefixStyle;
|
||||
|
||||
/// The Color to use for the [InputDecoration.prefixIcon].
|
||||
///
|
||||
/// If [prefixIconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [ColorScheme.primary].
|
||||
final Color? prefixIconColor;
|
||||
|
||||
/// The style to use for the [InputDecoration.suffixText].
|
||||
///
|
||||
/// If [suffixStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [hintStyle].
|
||||
final TextStyle? suffixStyle;
|
||||
|
||||
/// The Color to use for the [InputDecoration.suffixIcon].
|
||||
///
|
||||
/// If [suffixIconColor] is a [MaterialStateColor], then the effective
|
||||
/// color can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [ColorScheme.primary].
|
||||
final Color? suffixIconColor;
|
||||
|
||||
/// The style to use for the [InputDecoration.counterText].
|
||||
///
|
||||
/// If [counterStyle] is a [MaterialStateTextStyle], then the effective
|
||||
/// text style can depend on the [MaterialState.focused] state, i.e.
|
||||
/// if the [TextField] is focused or not.
|
||||
///
|
||||
/// If null, defaults to the [helperStyle].
|
||||
final TextStyle? counterStyle;
|
||||
|
||||
@ -4088,10 +3890,6 @@ class InputDecorationTheme with Diagnosticable {
|
||||
|
||||
/// The shape of the border to draw around the decoration's container.
|
||||
///
|
||||
/// If [border] is a [MaterialStateUnderlineInputBorder]
|
||||
/// or [MaterialStateOutlineInputBorder], then the effective border can depend on
|
||||
/// the [MaterialState.focused] state, i.e. if the [TextField] is focused or not.
|
||||
///
|
||||
/// The decoration's container is the area which is filled if [filled] is
|
||||
/// true and bordered per the [border]. It's the area adjacent to
|
||||
/// [InputDecoration.icon] and above the widgets that contain
|
||||
@ -4156,11 +3954,8 @@ class InputDecorationTheme with Diagnosticable {
|
||||
bool? isDense,
|
||||
EdgeInsetsGeometry? contentPadding,
|
||||
bool? isCollapsed,
|
||||
Color? iconColor,
|
||||
TextStyle? prefixStyle,
|
||||
Color? prefixIconColor,
|
||||
TextStyle? suffixStyle,
|
||||
Color? suffixIconColor,
|
||||
TextStyle? counterStyle,
|
||||
bool? filled,
|
||||
Color? fillColor,
|
||||
@ -4186,12 +3981,9 @@ class InputDecorationTheme with Diagnosticable {
|
||||
floatingLabelBehavior: floatingLabelBehavior ?? this.floatingLabelBehavior,
|
||||
isDense: isDense ?? this.isDense,
|
||||
contentPadding: contentPadding ?? this.contentPadding,
|
||||
iconColor: iconColor,
|
||||
isCollapsed: isCollapsed ?? this.isCollapsed,
|
||||
prefixStyle: prefixStyle ?? this.prefixStyle,
|
||||
prefixIconColor: prefixIconColor ?? this.prefixIconColor,
|
||||
suffixStyle: suffixStyle ?? this.suffixStyle,
|
||||
suffixIconColor: suffixIconColor ?? this.suffixIconColor,
|
||||
counterStyle: counterStyle ?? this.counterStyle,
|
||||
filled: filled ?? this.filled,
|
||||
fillColor: fillColor ?? this.fillColor,
|
||||
@ -4222,11 +4014,8 @@ class InputDecorationTheme with Diagnosticable {
|
||||
isDense,
|
||||
contentPadding,
|
||||
isCollapsed,
|
||||
iconColor,
|
||||
prefixStyle,
|
||||
prefixIconColor,
|
||||
suffixStyle,
|
||||
suffixIconColor,
|
||||
counterStyle,
|
||||
filled,
|
||||
fillColor,
|
||||
@ -4244,7 +4033,7 @@ class InputDecorationTheme with Diagnosticable {
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
bool operator==(Object other) {
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
@ -4260,11 +4049,8 @@ class InputDecorationTheme with Diagnosticable {
|
||||
&& other.isDense == isDense
|
||||
&& other.contentPadding == contentPadding
|
||||
&& other.isCollapsed == isCollapsed
|
||||
&& other.iconColor == iconColor
|
||||
&& other.prefixStyle == prefixStyle
|
||||
&& other.prefixIconColor == prefixIconColor
|
||||
&& other.suffixStyle == suffixStyle
|
||||
&& other.suffixIconColor == suffixIconColor
|
||||
&& other.counterStyle == counterStyle
|
||||
&& other.floatingLabelBehavior == floatingLabelBehavior
|
||||
&& other.filled == filled
|
||||
@ -4297,10 +4083,7 @@ class InputDecorationTheme with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<bool>('isDense', isDense, defaultValue: defaultTheme.isDense));
|
||||
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('contentPadding', contentPadding, defaultValue: defaultTheme.contentPadding));
|
||||
properties.add(DiagnosticsProperty<bool>('isCollapsed', isCollapsed, defaultValue: defaultTheme.isCollapsed));
|
||||
properties.add(DiagnosticsProperty<Color>('iconColor', iconColor, defaultValue: defaultTheme.iconColor));
|
||||
properties.add(DiagnosticsProperty<Color>('prefixIconColor', prefixIconColor, defaultValue: defaultTheme.prefixIconColor));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('prefixStyle', prefixStyle, defaultValue: defaultTheme.prefixStyle));
|
||||
properties.add(DiagnosticsProperty<Color>('suffixIconColor', suffixIconColor, defaultValue: defaultTheme.suffixIconColor));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('suffixStyle', suffixStyle, defaultValue: defaultTheme.suffixStyle));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('counterStyle', counterStyle, defaultValue: defaultTheme.counterStyle));
|
||||
properties.add(DiagnosticsProperty<bool>('filled', filled, defaultValue: defaultTheme.filled));
|
||||
|
@ -6,8 +6,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'input_border.dart';
|
||||
|
||||
/// Interactive states that some of the Material widgets can take on when
|
||||
/// receiving input from the user.
|
||||
///
|
||||
@ -98,9 +96,6 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
|
||||
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
|
||||
/// [MaterialState.focused] and [MaterialState.hovered].
|
||||
///
|
||||
/// [MaterialStateColor] should only be used with widgets that document
|
||||
/// their support, like [TimePickerThemeData.dayPeriodColor].
|
||||
///
|
||||
/// To use a [MaterialStateColor], you can either:
|
||||
/// 1. Create a subclass of [MaterialStateColor] and implement the abstract `resolve` method.
|
||||
/// 2. Use [MaterialStateColor.resolveWith] and pass in a callback that
|
||||
@ -115,6 +110,11 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
|
||||
/// to provide a `defaultValue` to the super constructor, so that we can know
|
||||
/// at compile-time what its default color is.
|
||||
///
|
||||
/// This class enables existing widget implementations with [Color]
|
||||
/// properties to be extended to also effectively support `MaterialStateProperty<Color>`
|
||||
/// property values. [MaterialStateColor] should only be used with widgets that document
|
||||
/// their support, like [TimePickerThemeData.dayPeriodColor].
|
||||
///
|
||||
/// {@tool snippet}
|
||||
///
|
||||
/// This example defines a `MaterialStateColor` with a const constructor.
|
||||
@ -391,196 +391,6 @@ abstract class MaterialStateOutlinedBorder extends OutlinedBorder implements Mat
|
||||
OutlinedBorder? resolve(Set<MaterialState> states);
|
||||
}
|
||||
|
||||
|
||||
/// Defines a [TextStyle] that is also a [MaterialStateProperty].
|
||||
///
|
||||
/// This class exists to enable widgets with [TextStyle] valued properties
|
||||
/// to also accept [MaterialStateProperty<TextStyle>] values. A material
|
||||
/// state text style property represents a text style which depends on
|
||||
/// a widget's "interactive state". This state is represented as a
|
||||
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
|
||||
/// [MaterialState.focused] and [MaterialState.hovered].
|
||||
///
|
||||
/// [MaterialStateTextStyle] should only be used with widgets that document
|
||||
/// their support, like [InputDecoration.labelStyle].
|
||||
///
|
||||
/// To use a [MaterialStateTextStyle], you can either:
|
||||
/// 1. Create a subclass of [MaterialStateTextStyle] and implement the abstract `resolve` method.
|
||||
/// 2. Use [MaterialStateTextStyle.resolveWith] and pass in a callback that
|
||||
/// will be used to resolve the color in the given states.
|
||||
///
|
||||
/// If a [MaterialStateTextStyle] is used for a property or a parameter that doesn't
|
||||
/// support resolving [MaterialStateProperty<TextStyle>]s, then its default color
|
||||
/// value will be used for all states.
|
||||
///
|
||||
/// To define a `const` [MaterialStateTextStyle], you'll need to extend
|
||||
/// [MaterialStateTextStyle] and override its [resolve] method. You'll also need
|
||||
/// to provide a `defaultValue` to the super constructor, so that we can know
|
||||
/// at compile-time what its default color is.
|
||||
abstract class MaterialStateTextStyle extends TextStyle implements MaterialStateProperty<TextStyle> {
|
||||
/// Abstract const constructor. This constructor enables subclasses to provide
|
||||
/// const constructors so that they can be used in const expressions.
|
||||
const MaterialStateTextStyle();
|
||||
|
||||
/// Creates a [MaterialStateTextStyle] from a [MaterialPropertyResolver<TextStyle>]
|
||||
/// callback function.
|
||||
///
|
||||
/// If used as a regular text style, the style resolved in the default state (the
|
||||
/// empty set of states) will be used.
|
||||
///
|
||||
/// The given callback parameter must return a non-null text style in the default
|
||||
/// state.
|
||||
static MaterialStateTextStyle resolveWith(MaterialPropertyResolver<TextStyle> callback) =>
|
||||
_MaterialStateTextStyle(callback);
|
||||
|
||||
/// Returns a [TextStyle] that's to be used when a Material component is in the
|
||||
/// specified state.
|
||||
@override
|
||||
TextStyle resolve(Set<MaterialState> states);
|
||||
}
|
||||
|
||||
/// A [MaterialStateTextStyle] created from a [MaterialPropertyResolver<TextStyle>]
|
||||
/// callback alone.
|
||||
///
|
||||
/// If used as a regular text style, the style resolved in the default state will
|
||||
/// be used.
|
||||
///
|
||||
/// Used by [MaterialStateTextStyle.resolveWith].
|
||||
class _MaterialStateTextStyle extends MaterialStateTextStyle {
|
||||
const _MaterialStateTextStyle(this._resolve);
|
||||
|
||||
final MaterialPropertyResolver<TextStyle> _resolve;
|
||||
|
||||
@override
|
||||
TextStyle resolve(Set<MaterialState> states) => _resolve(states);
|
||||
}
|
||||
|
||||
/// Defines a [OutlineInputBorder] that is also a [MaterialStateProperty].
|
||||
///
|
||||
/// This class exists to enable widgets with [OutlineInputBorder] valued properties
|
||||
/// to also accept [MaterialStateProperty<OutlineInputBorder>] values. A material
|
||||
/// state input border property represents a text style which depends on
|
||||
/// a widget's "interactive state". This state is represented as a
|
||||
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
|
||||
/// [MaterialState.focused] and [MaterialState.hovered].
|
||||
///
|
||||
/// [MaterialStateOutlineInputBorder] should only be used with widgets that document
|
||||
/// their support, like [InputDecoration.border].
|
||||
///
|
||||
/// To use a [MaterialStateOutlineInputBorder], you can either:
|
||||
/// 1. Create a subclass of [MaterialStateOutlineInputBorder] and implement the abstract `resolve` method.
|
||||
/// 2. Use [MaterialStateOutlineInputBorder.resolveWith] and pass in a callback that
|
||||
/// will be used to resolve the color in the given states.
|
||||
///
|
||||
/// If a [MaterialStateOutlineInputBorder] is used for a property or a parameter that doesn't
|
||||
/// support resolving [MaterialStateProperty<OutlineInputBorder>]s, then its default color
|
||||
/// value will be used for all states.
|
||||
///
|
||||
/// To define a `const` [MaterialStateOutlineInputBorder], you'll need to extend
|
||||
/// [MaterialStateOutlineInputBorder] and override its [resolve] method. You'll also need
|
||||
/// to provide a `defaultValue` to the super constructor, so that we can know
|
||||
/// at compile-time what its default color is.
|
||||
abstract class MaterialStateOutlineInputBorder extends OutlineInputBorder implements MaterialStateProperty<InputBorder> {
|
||||
/// Abstract const constructor. This constructor enables subclasses to provide
|
||||
/// const constructors so that they can be used in const expressions.
|
||||
const MaterialStateOutlineInputBorder();
|
||||
|
||||
/// Creates a [MaterialStateOutlineInputBorder] from a [MaterialPropertyResolver<InputBorder>]
|
||||
/// callback function.
|
||||
///
|
||||
/// If used as a regular input border, the border resolved in the default state (the
|
||||
/// empty set of states) will be used.
|
||||
///
|
||||
/// The given callback parameter must return a non-null text style in the default
|
||||
/// state.
|
||||
static MaterialStateOutlineInputBorder resolveWith(MaterialPropertyResolver<InputBorder> callback) =>
|
||||
_MaterialStateOutlineInputBorder(callback);
|
||||
|
||||
/// Returns a [InputBorder] that's to be used when a Material component is in the
|
||||
/// specified state.
|
||||
@override
|
||||
InputBorder resolve(Set<MaterialState> states);
|
||||
}
|
||||
|
||||
/// A [MaterialStateOutlineInputBorder] created from a [MaterialPropertyResolver<OutlineInputBorder>]
|
||||
/// callback alone.
|
||||
///
|
||||
/// If used as a regular input border, the border resolved in the default state will
|
||||
/// be used.
|
||||
///
|
||||
/// Used by [MaterialStateTextStyle.resolveWith].
|
||||
class _MaterialStateOutlineInputBorder extends MaterialStateOutlineInputBorder {
|
||||
const _MaterialStateOutlineInputBorder(this._resolve);
|
||||
|
||||
final MaterialPropertyResolver<InputBorder> _resolve;
|
||||
|
||||
@override
|
||||
InputBorder resolve(Set<MaterialState> states) => _resolve(states);
|
||||
}
|
||||
|
||||
/// Defines a [UnderlineInputBorder] that is also a [MaterialStateProperty].
|
||||
///
|
||||
/// This class exists to enable widgets with [UnderlineInputBorder] valued properties
|
||||
/// to also accept [MaterialStateProperty<UnderlineInputBorder>] values. A material
|
||||
/// state input border property represents a text style which depends on
|
||||
/// a widget's "interactive state". This state is represented as a
|
||||
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
|
||||
/// [MaterialState.focused] and [MaterialState.hovered].
|
||||
///
|
||||
/// [MaterialStateUnderlineInputBorder] should only be used with widgets that document
|
||||
/// their support, like [InputDecoration.border].
|
||||
///
|
||||
/// To use a [MaterialStateUnderlineInputBorder], you can either:
|
||||
/// 1. Create a subclass of [MaterialStateUnderlineInputBorder] and implement the abstract `resolve` method.
|
||||
/// 2. Use [MaterialStateUnderlineInputBorder.resolveWith] and pass in a callback that
|
||||
/// will be used to resolve the color in the given states.
|
||||
///
|
||||
/// If a [MaterialStateUnderlineInputBorder] is used for a property or a parameter that doesn't
|
||||
/// support resolving [MaterialStateProperty<UnderlineInputBorder>]s, then its default color
|
||||
/// value will be used for all states.
|
||||
///
|
||||
/// To define a `const` [MaterialStateUnderlineInputBorder], you'll need to extend
|
||||
/// [MaterialStateUnderlineInputBorder] and override its [resolve] method. You'll also need
|
||||
/// to provide a `defaultValue` to the super constructor, so that we can know
|
||||
/// at compile-time what its default color is.
|
||||
abstract class MaterialStateUnderlineInputBorder extends UnderlineInputBorder implements MaterialStateProperty<InputBorder> {
|
||||
/// Abstract const constructor. This constructor enables subclasses to provide
|
||||
/// const constructors so that they can be used in const expressions.
|
||||
const MaterialStateUnderlineInputBorder();
|
||||
|
||||
/// Creates a [MaterialStateUnderlineInputBorder] from a [MaterialPropertyResolver<InputBorder>]
|
||||
/// callback function.
|
||||
///
|
||||
/// If used as a regular ionput bortder, the border resolved in the default state (the
|
||||
/// empty set of states) will be used.
|
||||
///
|
||||
/// The given callback parameter must return a non-null text style in the default
|
||||
/// state.
|
||||
static MaterialStateUnderlineInputBorder resolveWith(MaterialPropertyResolver<InputBorder> callback) =>
|
||||
_MaterialStateUnderlineInputBorder(callback);
|
||||
|
||||
/// Returns a [InputBorder] that's to be used when a Material component is in the
|
||||
/// specified state.
|
||||
@override
|
||||
InputBorder resolve(Set<MaterialState> states);
|
||||
}
|
||||
|
||||
/// A [MaterialStateUnderlineInputBorder] created from a [MaterialPropertyResolver<UnderlineInputBorder>]
|
||||
/// callback alone.
|
||||
///
|
||||
/// If used as a regular input border, the border resolved in the default state will
|
||||
/// be used.
|
||||
///
|
||||
/// Used by [MaterialStateTextStyle.resolveWith].
|
||||
class _MaterialStateUnderlineInputBorder extends MaterialStateUnderlineInputBorder {
|
||||
const _MaterialStateUnderlineInputBorder(this._resolve);
|
||||
|
||||
final MaterialPropertyResolver<InputBorder> _resolve;
|
||||
|
||||
@override
|
||||
InputBorder resolve(Set<MaterialState> states) => _resolve(states);
|
||||
}
|
||||
|
||||
/// Interface for classes that [resolve] to a value of type `T` based
|
||||
/// on a widget's interactive "state", which is defined as a set
|
||||
/// of [MaterialState]s.
|
||||
|
@ -3664,110 +3664,6 @@ void main() {
|
||||
expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
|
||||
});
|
||||
|
||||
testWidgets('InputDecorationTheme.inputDecoration with MaterialState', (WidgetTester tester) async {
|
||||
final MaterialStateTextStyle themeStyle = MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
return const TextStyle(color: Colors.green);
|
||||
});
|
||||
|
||||
final MaterialStateTextStyle decorationStyle = MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
|
||||
return const TextStyle(color: Colors.blue);
|
||||
});
|
||||
|
||||
// InputDecorationTheme arguments define InputDecoration properties.
|
||||
InputDecoration decoration = const InputDecoration().applyDefaults(
|
||||
InputDecorationTheme(
|
||||
labelStyle: themeStyle,
|
||||
helperStyle: themeStyle,
|
||||
hintStyle: themeStyle,
|
||||
errorStyle: themeStyle,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(1.0),
|
||||
prefixStyle: themeStyle,
|
||||
suffixStyle: themeStyle,
|
||||
counterStyle: themeStyle,
|
||||
filled: true,
|
||||
fillColor: Colors.red,
|
||||
focusColor: Colors.blue,
|
||||
border: InputBorder.none,
|
||||
alignLabelWithHint: true,
|
||||
constraints: const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
|
||||
),
|
||||
);
|
||||
|
||||
expect(decoration.labelStyle, themeStyle);
|
||||
expect(decoration.helperStyle, themeStyle);
|
||||
expect(decoration.hintStyle, themeStyle);
|
||||
expect(decoration.errorStyle, themeStyle);
|
||||
expect(decoration.isDense, true);
|
||||
expect(decoration.contentPadding, const EdgeInsets.all(1.0));
|
||||
expect(decoration.prefixStyle, themeStyle);
|
||||
expect(decoration.suffixStyle, themeStyle);
|
||||
expect(decoration.counterStyle, themeStyle);
|
||||
expect(decoration.filled, true);
|
||||
expect(decoration.fillColor, Colors.red);
|
||||
expect(decoration.border, InputBorder.none);
|
||||
expect(decoration.alignLabelWithHint, true);
|
||||
expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
|
||||
|
||||
// InputDecoration (baseDecoration) defines InputDecoration properties
|
||||
final MaterialStateOutlineInputBorder border = MaterialStateOutlineInputBorder.resolveWith((Set<MaterialState> states) {
|
||||
return const OutlineInputBorder();
|
||||
});
|
||||
decoration = InputDecoration(
|
||||
labelStyle: decorationStyle,
|
||||
helperStyle: decorationStyle,
|
||||
hintStyle: decorationStyle,
|
||||
errorStyle: decorationStyle,
|
||||
isDense: false,
|
||||
contentPadding: const EdgeInsets.all(4.0),
|
||||
prefixStyle: decorationStyle,
|
||||
suffixStyle: decorationStyle,
|
||||
counterStyle: decorationStyle,
|
||||
filled: false,
|
||||
fillColor: Colors.blue,
|
||||
border: border,
|
||||
alignLabelWithHint: false,
|
||||
constraints: const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
|
||||
).applyDefaults(
|
||||
InputDecorationTheme(
|
||||
labelStyle: themeStyle,
|
||||
helperStyle: themeStyle,
|
||||
helperMaxLines: 5,
|
||||
hintStyle: themeStyle,
|
||||
errorStyle: themeStyle,
|
||||
errorMaxLines: 4,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(1.0),
|
||||
prefixStyle: themeStyle,
|
||||
suffixStyle: themeStyle,
|
||||
counterStyle: themeStyle,
|
||||
filled: true,
|
||||
fillColor: Colors.red,
|
||||
focusColor: Colors.blue,
|
||||
border: InputBorder.none,
|
||||
alignLabelWithHint: true,
|
||||
constraints: const BoxConstraints(minWidth: 40, maxWidth: 30, minHeight: 20, maxHeight: 10),
|
||||
),
|
||||
);
|
||||
|
||||
expect(decoration.labelStyle, decorationStyle);
|
||||
expect(decoration.helperStyle, decorationStyle);
|
||||
expect(decoration.helperMaxLines, 5);
|
||||
expect(decoration.hintStyle, decorationStyle);
|
||||
expect(decoration.errorStyle, decorationStyle);
|
||||
expect(decoration.errorMaxLines, 4);
|
||||
expect(decoration.isDense, false);
|
||||
expect(decoration.contentPadding, const EdgeInsets.all(4.0));
|
||||
expect(decoration.prefixStyle, decorationStyle);
|
||||
expect(decoration.suffixStyle, decorationStyle);
|
||||
expect(decoration.counterStyle, decorationStyle);
|
||||
expect(decoration.filled, false);
|
||||
expect(decoration.fillColor, Colors.blue);
|
||||
expect(decoration.border, isA<MaterialStateOutlineInputBorder>());
|
||||
expect(decoration.alignLabelWithHint, false);
|
||||
expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
|
||||
});
|
||||
|
||||
testWidgets('InputDecorator OutlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/15742
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user