Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
64b0cfda
Unverified
Commit
64b0cfda
authored
Oct 14, 2021
by
Bjarte Bore
Committed by
GitHub
Oct 14, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for MaterialState to InputDecorator (#91762)
parent
06e75e94
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
688 additions
and
60 deletions
+688
-60
input_decoration.material_state.0.dart
...al/input_decorator/input_decoration.material_state.0.dart
+48
-0
input_decoration.material_state.1.dart
...al/input_decorator/input_decoration.material_state.1.dart
+55
-0
input_decorator.dart
packages/flutter/lib/src/material/input_decorator.dart
+286
-55
material_state.dart
packages/flutter/lib/src/material/material_state.dart
+195
-5
input_decorator_test.dart
packages/flutter/test/material/input_decorator_test.dart
+104
-0
No files found.
examples/api/lib/material/input_decorator/input_decoration.material_state.0.dart
0 → 100644
View file @
64b0cfda
// 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
;
}),
),
);
}
}
examples/api/lib/material/input_decorator/input_decoration.material_state.1.dart
0 → 100644
View file @
64b0cfda
// 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
),
),
),
);
}
}
packages/flutter/lib/src/material/input_decorator.dart
View file @
64b0cfda
...
@@ -12,6 +12,7 @@ import 'package:flutter/widgets.dart';
...
@@ -12,6 +12,7 @@ import 'package:flutter/widgets.dart';
import
'colors.dart'
;
import
'colors.dart'
;
import
'constants.dart'
;
import
'constants.dart'
;
import
'input_border.dart'
;
import
'input_border.dart'
;
import
'material_state.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
import
'theme_data.dart'
;
import
'theme_data.dart'
;
...
@@ -2081,7 +2082,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2081,7 +2082,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
if
(
decoration
!.
filled
!=
true
)
// filled == null same as filled == false
if
(
decoration
!.
filled
!=
true
)
// filled == null same as filled == false
return
Colors
.
transparent
;
return
Colors
.
transparent
;
if
(
decoration
!.
fillColor
!=
null
)
if
(
decoration
!.
fillColor
!=
null
)
return
decoration
!.
fillColor
!
;
return
MaterialStateProperty
.
resolveAs
(
decoration
!.
fillColor
!,
materialState
)
;
// dark theme: 10% white (enabled), 5% white (disabled)
// dark theme: 10% white (enabled), 5% white (disabled)
// light theme: 4% black (enabled), 2% black (disabled)
// light theme: 4% black (enabled), 2% black (disabled)
...
@@ -2104,16 +2105,33 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2104,16 +2105,33 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return
decoration
!.
hoverColor
??
themeData
.
inputDecorationTheme
.
hoverColor
??
themeData
.
hoverColor
;
return
decoration
!.
hoverColor
??
themeData
.
inputDecorationTheme
.
hoverColor
??
themeData
.
hoverColor
;
}
}
Color
_getDefaultIconColor
(
ThemeData
themeData
)
{
Color
_getIconColor
(
ThemeData
themeData
)
{
if
(!
decoration
!.
enabled
&&
!
isFocused
)
Color
_resolveIconColor
(
Set
<
MaterialState
>
states
)
{
return
themeData
.
disabledColor
;
if
(
states
.
contains
(
MaterialState
.
disabled
)
&&
!
states
.
contains
(
MaterialState
.
focused
))
return
themeData
.
disabledColor
;
switch
(
themeData
.
brightness
)
{
if
(
states
.
contains
(
MaterialState
.
focused
))
case
Brightness
.
dark
:
return
themeData
.
colorScheme
.
primary
;
return
Colors
.
white70
;
case
Brightness
.
light
:
switch
(
themeData
.
brightness
)
{
return
Colors
.
black45
;
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.
// True if the label will be shown and the hint will not.
...
@@ -2129,34 +2147,68 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2129,34 +2147,68 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
// If the label is a floating placeholder, it's always shown.
// If the label is a floating placeholder, it's always shown.
bool
get
_shouldShowLabel
=>
_hasInlineLabel
||
_floatingLabelEnabled
;
bool
get
_shouldShowLabel
=>
_hasInlineLabel
||
_floatingLabelEnabled
;
// The base style for the inline label
or hint
when they're displayed "inline",
// The base style for the inline label when they're displayed "inline",
// i.e. when they appear in place of the empty text field.
// i.e. when they appear in place of the empty text field.
TextStyle
_getInlineStyle
(
ThemeData
themeData
)
{
TextStyle
_getInlineLabelStyle
(
ThemeData
themeData
)
{
return
themeData
.
textTheme
.
subtitle1
!.
merge
(
widget
.
baseStyle
)
final
TextStyle
defaultStyle
=
TextStyle
(
.
copyWith
(
color:
decoration
!.
enabled
?
themeData
.
hintColor
:
themeData
.
disabledColor
);
color:
decoration
!.
enabled
?
themeData
.
hintColor
:
themeData
.
disabledColor
,
);
final
TextStyle
?
style
=
MaterialStateProperty
.
resolveAs
(
decoration
!.
labelStyle
,
materialState
)
??
MaterialStateProperty
.
resolveAs
(
themeData
.
inputDecorationTheme
.
labelStyle
,
materialState
);
return
themeData
.
textTheme
.
subtitle1
!
.
merge
(
widget
.
baseStyle
)
.
merge
(
defaultStyle
)
.
merge
(
style
)
// 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.
.
copyWith
(
height:
themeData
.
fixTextFieldOutlineLabel
?
1
:
null
);
}
// The base style for the inline hint when they're displayed "inline",
// 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
,
);
final
TextStyle
?
style
=
MaterialStateProperty
.
resolveAs
(
decoration
!.
hintStyle
,
materialState
)
??
MaterialStateProperty
.
resolveAs
(
themeData
.
inputDecorationTheme
.
hintStyle
,
materialState
);
return
themeData
.
textTheme
.
subtitle1
!
.
merge
(
widget
.
baseStyle
)
.
merge
(
defaultStyle
)
.
merge
(
style
);
}
}
TextStyle
_getFloatingLabelStyle
(
ThemeData
themeData
)
{
TextStyle
_getFloatingLabelStyle
(
ThemeData
themeData
)
{
final
Color
color
=
decoration
!.
errorText
!=
null
TextStyle
getFallbackTextStyle
()
{
?
decoration
!.
errorStyle
?.
color
??
themeData
.
errorColor
final
Color
color
=
decoration
!.
errorText
!=
null
:
_getActiveColor
(
themeData
);
?
decoration
!.
errorStyle
?.
color
??
themeData
.
errorColor
final
TextStyle
style
=
themeData
.
textTheme
.
subtitle1
!.
merge
(
widget
.
baseStyle
);
:
_getActiveColor
(
themeData
);
// 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
return
TextStyle
(
color:
decoration
!.
enabled
?
color
:
themeData
.
disabledColor
)
// 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
);
.
merge
(
decoration
!.
floatingLabelStyle
??
decoration
!.
labelStyle
);
}
final
TextStyle
?
style
=
MaterialStateProperty
.
resolveAs
(
decoration
!.
floatingLabelStyle
,
materialState
)
??
MaterialStateProperty
.
resolveAs
(
themeData
.
inputDecorationTheme
.
floatingLabelStyle
,
materialState
);
return
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.
.
copyWith
(
height:
themeData
.
fixTextFieldOutlineLabel
?
1
:
null
)
.
merge
(
getFallbackTextStyle
())
.
merge
(
style
);
}
}
TextStyle
_getHelperStyle
(
ThemeData
themeData
)
{
TextStyle
_getHelperStyle
(
ThemeData
themeData
)
{
final
Color
color
=
decoration
!.
enabled
?
themeData
.
hintColor
:
Colors
.
transparent
;
final
Color
color
=
decoration
!.
enabled
?
themeData
.
hintColor
:
Colors
.
transparent
;
return
themeData
.
textTheme
.
caption
!.
copyWith
(
color:
color
).
merge
(
decoration
!.
helperStyle
);
return
themeData
.
textTheme
.
caption
!.
copyWith
(
color:
color
).
merge
(
MaterialStateProperty
.
resolveAs
(
decoration
!.
helperStyle
,
materialState
)
);
}
}
TextStyle
_getErrorStyle
(
ThemeData
themeData
)
{
TextStyle
_getErrorStyle
(
ThemeData
themeData
)
{
...
@@ -2164,9 +2216,25 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2164,9 +2216,25 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
return
themeData
.
textTheme
.
caption
!.
copyWith
(
color:
color
).
merge
(
decoration
!.
errorStyle
);
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
)
{
InputBorder
_getDefaultBorder
(
ThemeData
themeData
)
{
if
(
decoration
!.
border
?.
borderSide
==
BorderSide
.
none
)
{
final
InputBorder
border
=
MaterialStateProperty
.
resolveAs
(
decoration
!.
border
,
materialState
)
return
decoration
!.
border
!;
??
const
UnderlineInputBorder
();
if
(
decoration
!.
border
is
MaterialStateProperty
<
InputBorder
>)
{
return
border
;
}
if
(
border
.
borderSide
==
BorderSide
.
none
)
{
return
border
;
}
}
final
Color
borderColor
;
final
Color
borderColor
;
...
@@ -2186,17 +2254,16 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2186,17 +2254,16 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
else
else
borderWeight
=
isFocused
?
2.0
:
1.0
;
borderWeight
=
isFocused
?
2.0
:
1.0
;
final
InputBorder
border
=
decoration
!.
border
??
const
UnderlineInputBorder
();
return
border
.
copyWith
(
borderSide:
BorderSide
(
color:
borderColor
,
width:
borderWeight
));
return
border
.
copyWith
(
borderSide:
BorderSide
(
color:
borderColor
,
width:
borderWeight
));
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
ThemeData
themeData
=
Theme
.
of
(
context
);
final
ThemeData
themeData
=
Theme
.
of
(
context
);
final
TextStyle
inlineStyle
=
_getInline
Style
(
themeData
);
final
TextStyle
labelStyle
=
_getInlineLabel
Style
(
themeData
);
final
TextBaseline
textBaseline
=
inline
Style
.
textBaseline
!;
final
TextBaseline
textBaseline
=
label
Style
.
textBaseline
!;
final
TextStyle
hintStyle
=
inlineStyle
.
merge
(
decoration
!.
hintStyle
);
final
TextStyle
hintStyle
=
_getInlineHintStyle
(
themeData
);
final
Widget
?
hint
=
decoration
!.
hintText
==
null
?
null
:
AnimatedOpacity
(
final
Widget
?
hint
=
decoration
!.
hintText
==
null
?
null
:
AnimatedOpacity
(
opacity:
(
isEmpty
&&
!
_hasInlineLabel
)
?
1.0
:
0.0
,
opacity:
(
isEmpty
&&
!
_hasInlineLabel
)
?
1.0
:
0.0
,
duration:
_kTransitionDuration
,
duration:
_kTransitionDuration
,
...
@@ -2231,12 +2298,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2231,12 +2298,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
isHovering:
isHovering
,
isHovering:
isHovering
,
);
);
// 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.
final
TextStyle
inlineLabelStyle
=
themeData
.
fixTextFieldOutlineLabel
?
inlineStyle
.
merge
(
decoration
!.
labelStyle
).
copyWith
(
height:
1
)
:
inlineStyle
.
merge
(
decoration
!.
labelStyle
);
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
,
animation:
_shakingLabelController
.
view
,
child:
AnimatedOpacity
(
child:
AnimatedOpacity
(
...
@@ -2248,7 +2309,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2248,7 +2309,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
curve:
_kTransitionCurve
,
curve:
_kTransitionCurve
,
style:
widget
.
_labelShouldWithdraw
style:
widget
.
_labelShouldWithdraw
?
_getFloatingLabelStyle
(
themeData
)
?
_getFloatingLabelStyle
(
themeData
)
:
inlineL
abelStyle
,
:
l
abelStyle
,
child:
decoration
!.
label
??
Text
(
child:
decoration
!.
label
??
Text
(
decoration
!.
labelText
!,
decoration
!.
labelText
!,
overflow:
TextOverflow
.
ellipsis
,
overflow:
TextOverflow
.
ellipsis
,
...
@@ -2262,7 +2323,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2262,7 +2323,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
_AffixText
(
_AffixText
(
labelIsFloating:
widget
.
_labelShouldWithdraw
,
labelIsFloating:
widget
.
_labelShouldWithdraw
,
text:
decoration
!.
prefixText
,
text:
decoration
!.
prefixText
,
style:
decoration
!.
prefixStyle
??
hintStyle
,
style:
MaterialStateProperty
.
resolveAs
(
decoration
!.
prefixStyle
,
materialState
)
??
hintStyle
,
child:
decoration
!.
prefix
,
child:
decoration
!.
prefix
,
);
);
...
@@ -2270,21 +2331,20 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2270,21 +2331,20 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
_AffixText
(
_AffixText
(
labelIsFloating:
widget
.
_labelShouldWithdraw
,
labelIsFloating:
widget
.
_labelShouldWithdraw
,
text:
decoration
!.
suffixText
,
text:
decoration
!.
suffixText
,
style:
decoration
!.
suffixStyle
??
hintStyle
,
style:
MaterialStateProperty
.
resolveAs
(
decoration
!.
suffixStyle
,
materialState
)
??
hintStyle
,
child:
decoration
!.
suffix
,
child:
decoration
!.
suffix
,
);
);
final
Color
activeColor
=
_getActiveColor
(
themeData
);
final
bool
decorationIsDense
=
decoration
!.
isDense
==
true
;
// isDense == null, same as false
final
bool
decorationIsDense
=
decoration
!.
isDense
==
true
;
// isDense == null, same as false
final
double
iconSize
=
decorationIsDense
?
18.0
:
24.0
;
final
double
iconSize
=
decorationIsDense
?
18.0
:
24.0
;
final
Color
iconColor
=
isFocused
?
activeColor
:
_getDefaultIconColor
(
themeData
);
final
Widget
?
icon
=
decoration
!.
icon
==
null
?
null
:
final
Widget
?
icon
=
decoration
!.
icon
==
null
?
null
:
Padding
(
Padding
(
padding:
const
EdgeInsetsDirectional
.
only
(
end:
16.0
),
padding:
const
EdgeInsetsDirectional
.
only
(
end:
16.0
),
child:
IconTheme
.
merge
(
child:
IconTheme
.
merge
(
data:
IconThemeData
(
data:
IconThemeData
(
color:
iconColor
,
color:
_getIconColor
(
themeData
)
,
size:
iconSize
,
size:
iconSize
,
),
),
child:
decoration
!.
icon
!,
child:
decoration
!.
icon
!,
...
@@ -2304,7 +2364,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2304,7 +2364,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
),
),
child:
IconTheme
.
merge
(
child:
IconTheme
.
merge
(
data:
IconThemeData
(
data:
IconThemeData
(
color:
iconColor
,
color:
_getPrefixIconColor
(
themeData
)
,
size:
iconSize
,
size:
iconSize
,
),
),
child:
decoration
!.
prefixIcon
!,
child:
decoration
!.
prefixIcon
!,
...
@@ -2325,7 +2385,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2325,7 +2385,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
),
),
child:
IconTheme
.
merge
(
child:
IconTheme
.
merge
(
data:
IconThemeData
(
data:
IconThemeData
(
color:
iconColor
,
color:
_getSuffixIconColor
(
themeData
)
,
size:
iconSize
,
size:
iconSize
,
),
),
child:
decoration
!.
suffixIcon
!,
child:
decoration
!.
suffixIcon
!,
...
@@ -2352,7 +2412,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2352,7 +2412,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
liveRegion:
isFocused
,
liveRegion:
isFocused
,
child:
Text
(
child:
Text
(
decoration
!.
counterText
!,
decoration
!.
counterText
!,
style:
_getHelperStyle
(
themeData
).
merge
(
decoration
!.
counterStyle
),
style:
_getHelperStyle
(
themeData
).
merge
(
MaterialStateProperty
.
resolveAs
(
decoration
!.
counterStyle
,
materialState
)
),
overflow:
TextOverflow
.
ellipsis
,
overflow:
TextOverflow
.
ellipsis
,
semanticsLabel:
decoration
!.
semanticCounterText
,
semanticsLabel:
decoration
!.
semanticCounterText
,
),
),
...
@@ -2371,7 +2431,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2371,7 +2431,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
contentPadding
=
decorationContentPadding
??
EdgeInsets
.
zero
;
contentPadding
=
decorationContentPadding
??
EdgeInsets
.
zero
;
}
else
if
(!
border
.
isOutline
)
{
}
else
if
(!
border
.
isOutline
)
{
// 4.0: the vertical gap between the inline elements and the floating label.
// 4.0: the vertical gap between the inline elements and the floating label.
floatingLabelHeight
=
(
4.0
+
0.75
*
inlineL
abelStyle
.
fontSize
!)
*
MediaQuery
.
textScaleFactorOf
(
context
);
floatingLabelHeight
=
(
4.0
+
0.75
*
l
abelStyle
.
fontSize
!)
*
MediaQuery
.
textScaleFactorOf
(
context
);
if
(
decoration
!.
filled
==
true
)
{
// filled == null same as filled == false
if
(
decoration
!.
filled
==
true
)
{
// filled == null same as filled == false
contentPadding
=
decorationContentPadding
??
(
decorationIsDense
contentPadding
=
decorationContentPadding
??
(
decorationIsDense
?
const
EdgeInsets
.
fromLTRB
(
12.0
,
8.0
,
12.0
,
8.0
)
?
const
EdgeInsets
.
fromLTRB
(
12.0
,
8.0
,
12.0
,
8.0
)
...
@@ -2482,6 +2542,22 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
...
@@ -2482,6 +2542,22 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
/// ** See code in examples/api/lib/material/input_decorator/input_decoration.3.dart **
/// ** See code in examples/api/lib/material/input_decorator/input_decoration.3.dart **
/// {@end-tool}
/// {@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:
/// See also:
///
///
/// * [TextField], which is a text input widget that uses an
/// * [TextField], which is a text input widget that uses an
...
@@ -2507,6 +2583,7 @@ class InputDecoration {
...
@@ -2507,6 +2583,7 @@ class InputDecoration {
/// Similarly, only one of [suffix] and [suffixText] can be specified.
/// Similarly, only one of [suffix] and [suffixText] can be specified.
const
InputDecoration
({
const
InputDecoration
({
this
.
icon
,
this
.
icon
,
this
.
iconColor
,
this
.
label
,
this
.
label
,
this
.
labelText
,
this
.
labelText
,
this
.
labelStyle
,
this
.
labelStyle
,
...
@@ -2530,10 +2607,12 @@ class InputDecoration {
...
@@ -2530,10 +2607,12 @@ class InputDecoration {
this
.
prefix
,
this
.
prefix
,
this
.
prefixText
,
this
.
prefixText
,
this
.
prefixStyle
,
this
.
prefixStyle
,
this
.
prefixIconColor
,
this
.
suffixIcon
,
this
.
suffixIcon
,
this
.
suffix
,
this
.
suffix
,
this
.
suffixText
,
this
.
suffixText
,
this
.
suffixStyle
,
this
.
suffixStyle
,
this
.
suffixIconColor
,
this
.
suffixIconConstraints
,
this
.
suffixIconConstraints
,
this
.
counter
,
this
.
counter
,
this
.
counterText
,
this
.
counterText
,
...
@@ -2575,6 +2654,7 @@ class InputDecoration {
...
@@ -2575,6 +2654,7 @@ class InputDecoration {
this
.
enabled
=
true
,
this
.
enabled
=
true
,
})
:
assert
(
enabled
!=
null
),
})
:
assert
(
enabled
!=
null
),
icon
=
null
,
icon
=
null
,
iconColor
=
null
,
label
=
null
,
label
=
null
,
labelText
=
null
,
labelText
=
null
,
labelStyle
=
null
,
labelStyle
=
null
,
...
@@ -2593,11 +2673,13 @@ class InputDecoration {
...
@@ -2593,11 +2673,13 @@ class InputDecoration {
prefix
=
null
,
prefix
=
null
,
prefixText
=
null
,
prefixText
=
null
,
prefixStyle
=
null
,
prefixStyle
=
null
,
prefixIconColor
=
null
,
prefixIconConstraints
=
null
,
prefixIconConstraints
=
null
,
suffix
=
null
,
suffix
=
null
,
suffixIcon
=
null
,
suffixIcon
=
null
,
suffixText
=
null
,
suffixText
=
null
,
suffixStyle
=
null
,
suffixStyle
=
null
,
suffixIconColor
=
null
,
suffixIconConstraints
=
null
,
suffixIconConstraints
=
null
,
counter
=
null
,
counter
=
null
,
counterText
=
null
,
counterText
=
null
,
...
@@ -2628,6 +2710,13 @@ class InputDecoration {
...
@@ -2628,6 +2710,13 @@ class InputDecoration {
/// See [Icon], [ImageIcon].
/// See [Icon], [ImageIcon].
final
Widget
?
icon
;
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.
/// Optional widget that describes the input field.
///
///
/// {@template flutter.material.inputDecoration.label}
/// {@template flutter.material.inputDecoration.label}
...
@@ -2662,6 +2751,10 @@ class InputDecoration {
...
@@ -2662,6 +2751,10 @@ class InputDecoration {
/// The style to use for the [labelText] when the label is on top of the
/// The style to use for the [labelText] when the label is on top of the
/// input field.
/// 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
/// When the [labelText] is above (i.e., vertically adjacent to) the input
/// field, the text uses the [floatingLabelStyle] instead.
/// field, the text uses the [floatingLabelStyle] instead.
///
///
...
@@ -2672,6 +2765,10 @@ class InputDecoration {
...
@@ -2672,6 +2765,10 @@ class InputDecoration {
/// The style to use for the [labelText] when the label is above (i.e.,
/// The style to use for the [labelText] when the label is above (i.e.,
/// vertically adjacent to) the input field.
/// 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].
/// If null, defaults to [labelStyle].
final
TextStyle
?
floatingLabelStyle
;
final
TextStyle
?
floatingLabelStyle
;
...
@@ -2684,6 +2781,10 @@ class InputDecoration {
...
@@ -2684,6 +2781,10 @@ class InputDecoration {
final
String
?
helperText
;
final
String
?
helperText
;
/// The style to use for the [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
;
final
TextStyle
?
helperStyle
;
/// The maximum number of lines the [helperText] can occupy.
/// The maximum number of lines the [helperText] can occupy.
...
@@ -2709,6 +2810,10 @@ class InputDecoration {
...
@@ -2709,6 +2810,10 @@ class InputDecoration {
/// The style to use for the [hintText].
/// 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
/// 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
/// top of the input field (i.e., at the same location on the screen where
/// text may be entered in the [InputDecorator.child]).
/// text may be entered in the [InputDecorator.child]).
...
@@ -2904,6 +3009,10 @@ class InputDecoration {
...
@@ -2904,6 +3009,10 @@ class InputDecoration {
/// The style to use for the [prefixText].
/// 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].
/// If null, defaults to the [hintStyle].
///
///
/// See also:
/// See also:
...
@@ -2911,6 +3020,15 @@ class InputDecoration {
...
@@ -2911,6 +3020,15 @@ class InputDecoration {
/// * [suffixStyle], the equivalent but on the trailing edge.
/// * [suffixStyle], the equivalent but on the trailing edge.
final
TextStyle
?
prefixStyle
;
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
/// An icon that appears after the editable part of the text field and
/// after the [suffix] or [suffixText], within the decoration's container.
/// after the [suffix] or [suffixText], within the decoration's container.
///
///
...
@@ -2977,6 +3095,10 @@ class InputDecoration {
...
@@ -2977,6 +3095,10 @@ class InputDecoration {
/// The style to use for the [suffixText].
/// 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].
/// If null, defaults to the [hintStyle].
///
///
/// See also:
/// See also:
...
@@ -2984,6 +3106,15 @@ class InputDecoration {
...
@@ -2984,6 +3106,15 @@ class InputDecoration {
/// * [prefixStyle], the equivalent but on the leading edge.
/// * [prefixStyle], the equivalent but on the leading edge.
final
TextStyle
?
suffixStyle
;
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.
/// The constraints for the suffix icon.
///
///
/// This can be used to modify the [BoxConstraints] surrounding [suffixIcon].
/// This can be used to modify the [BoxConstraints] surrounding [suffixIcon].
...
@@ -3028,6 +3159,10 @@ class InputDecoration {
...
@@ -3028,6 +3159,10 @@ class InputDecoration {
/// The style to use for the [counterText].
/// 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].
/// If null, defaults to the [helperStyle].
final
TextStyle
?
counterStyle
;
final
TextStyle
?
counterStyle
;
...
@@ -3204,11 +3339,15 @@ class InputDecoration {
...
@@ -3204,11 +3339,15 @@ class InputDecoration {
/// The shape of the border to draw around the decoration's container.
/// The shape of the border to draw around the decoration's container.
///
///
/// This border's [InputBorder.borderSide], i.e. the border's color and width,
/// If [border] is a [MaterialStateUnderlineInputBorder]
/// will be overridden to reflect the input decorator's state. Only the
/// or [MaterialStateOutlineInputBorder], then the effective border can depend on
/// border's shape is used. If custom [BorderSide] values are desired for
/// the [MaterialState.focused] state, i.e. if the [TextField] is focused or not.
/// a given state, all four borders – [errorBorder], [focusedBorder],
///
/// [enabledBorder], [disabledBorder] – must be set.
/// 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.
///
///
/// The decoration's container is the area which is filled if [filled] is
/// 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
/// true and bordered per the [border]. It's the area adjacent to
...
@@ -3276,6 +3415,7 @@ class InputDecoration {
...
@@ -3276,6 +3415,7 @@ class InputDecoration {
/// by the new values.
/// by the new values.
InputDecoration
copyWith
({
InputDecoration
copyWith
({
Widget
?
icon
,
Widget
?
icon
,
Color
?
iconColor
,
Widget
?
label
,
Widget
?
label
,
String
?
labelText
,
String
?
labelText
,
TextStyle
?
labelStyle
,
TextStyle
?
labelStyle
,
...
@@ -3299,10 +3439,12 @@ class InputDecoration {
...
@@ -3299,10 +3439,12 @@ class InputDecoration {
String
?
prefixText
,
String
?
prefixText
,
BoxConstraints
?
prefixIconConstraints
,
BoxConstraints
?
prefixIconConstraints
,
TextStyle
?
prefixStyle
,
TextStyle
?
prefixStyle
,
Color
?
prefixIconColor
,
Widget
?
suffixIcon
,
Widget
?
suffixIcon
,
Widget
?
suffix
,
Widget
?
suffix
,
String
?
suffixText
,
String
?
suffixText
,
TextStyle
?
suffixStyle
,
TextStyle
?
suffixStyle
,
Color
?
suffixIconColor
,
BoxConstraints
?
suffixIconConstraints
,
BoxConstraints
?
suffixIconConstraints
,
Widget
?
counter
,
Widget
?
counter
,
String
?
counterText
,
String
?
counterText
,
...
@@ -3324,6 +3466,7 @@ class InputDecoration {
...
@@ -3324,6 +3466,7 @@ class InputDecoration {
})
{
})
{
return
InputDecoration
(
return
InputDecoration
(
icon:
icon
??
this
.
icon
,
icon:
icon
??
this
.
icon
,
iconColor:
iconColor
??
this
.
iconColor
,
label:
label
??
this
.
label
,
label:
label
??
this
.
label
,
labelText:
labelText
??
this
.
labelText
,
labelText:
labelText
??
this
.
labelText
,
labelStyle:
labelStyle
??
this
.
labelStyle
,
labelStyle:
labelStyle
??
this
.
labelStyle
,
...
@@ -3346,11 +3489,13 @@ class InputDecoration {
...
@@ -3346,11 +3489,13 @@ class InputDecoration {
prefix:
prefix
??
this
.
prefix
,
prefix:
prefix
??
this
.
prefix
,
prefixText:
prefixText
??
this
.
prefixText
,
prefixText:
prefixText
??
this
.
prefixText
,
prefixStyle:
prefixStyle
??
this
.
prefixStyle
,
prefixStyle:
prefixStyle
??
this
.
prefixStyle
,
prefixIconColor:
prefixIconColor
??
this
.
prefixIconColor
,
prefixIconConstraints:
prefixIconConstraints
??
this
.
prefixIconConstraints
,
prefixIconConstraints:
prefixIconConstraints
??
this
.
prefixIconConstraints
,
suffixIcon:
suffixIcon
??
this
.
suffixIcon
,
suffixIcon:
suffixIcon
??
this
.
suffixIcon
,
suffix:
suffix
??
this
.
suffix
,
suffix:
suffix
??
this
.
suffix
,
suffixText:
suffixText
??
this
.
suffixText
,
suffixText:
suffixText
??
this
.
suffixText
,
suffixStyle:
suffixStyle
??
this
.
suffixStyle
,
suffixStyle:
suffixStyle
??
this
.
suffixStyle
,
suffixIconColor:
suffixIconColor
??
this
.
suffixIconColor
,
suffixIconConstraints:
suffixIconConstraints
??
this
.
suffixIconConstraints
,
suffixIconConstraints:
suffixIconConstraints
??
this
.
suffixIconConstraints
,
counter:
counter
??
this
.
counter
,
counter:
counter
??
this
.
counter
,
counterText:
counterText
??
this
.
counterText
,
counterText:
counterText
??
this
.
counterText
,
...
@@ -3416,6 +3561,7 @@ class InputDecoration {
...
@@ -3416,6 +3561,7 @@ class InputDecoration {
return
false
;
return
false
;
return
other
is
InputDecoration
return
other
is
InputDecoration
&&
other
.
icon
==
icon
&&
other
.
icon
==
icon
&&
other
.
iconColor
==
iconColor
&&
other
.
label
==
label
&&
other
.
label
==
label
&&
other
.
labelText
==
labelText
&&
other
.
labelText
==
labelText
&&
other
.
labelStyle
==
labelStyle
&&
other
.
labelStyle
==
labelStyle
...
@@ -3435,11 +3581,13 @@ class InputDecoration {
...
@@ -3435,11 +3581,13 @@ class InputDecoration {
&&
other
.
contentPadding
==
contentPadding
&&
other
.
contentPadding
==
contentPadding
&&
other
.
isCollapsed
==
isCollapsed
&&
other
.
isCollapsed
==
isCollapsed
&&
other
.
prefixIcon
==
prefixIcon
&&
other
.
prefixIcon
==
prefixIcon
&&
other
.
prefixIconColor
==
prefixIconColor
&&
other
.
prefix
==
prefix
&&
other
.
prefix
==
prefix
&&
other
.
prefixText
==
prefixText
&&
other
.
prefixText
==
prefixText
&&
other
.
prefixStyle
==
prefixStyle
&&
other
.
prefixStyle
==
prefixStyle
&&
other
.
prefixIconConstraints
==
prefixIconConstraints
&&
other
.
prefixIconConstraints
==
prefixIconConstraints
&&
other
.
suffixIcon
==
suffixIcon
&&
other
.
suffixIcon
==
suffixIcon
&&
other
.
suffixIconColor
==
suffixIconColor
&&
other
.
suffix
==
suffix
&&
other
.
suffix
==
suffix
&&
other
.
suffixText
==
suffixText
&&
other
.
suffixText
==
suffixText
&&
other
.
suffixStyle
==
suffixStyle
&&
other
.
suffixStyle
==
suffixStyle
...
@@ -3467,6 +3615,7 @@ class InputDecoration {
...
@@ -3467,6 +3615,7 @@ class InputDecoration {
int
get
hashCode
{
int
get
hashCode
{
final
List
<
Object
?>
values
=
<
Object
?>[
final
List
<
Object
?>
values
=
<
Object
?>[
icon
,
icon
,
iconColor
,
label
,
label
,
labelText
,
labelText
,
floatingLabelStyle
,
floatingLabelStyle
,
...
@@ -3492,11 +3641,13 @@ class InputDecoration {
...
@@ -3492,11 +3641,13 @@ class InputDecoration {
border
,
border
,
enabled
,
enabled
,
prefixIcon
,
prefixIcon
,
prefixIconColor
,
prefix
,
prefix
,
prefixText
,
prefixText
,
prefixStyle
,
prefixStyle
,
prefixIconConstraints
,
prefixIconConstraints
,
suffixIcon
,
suffixIcon
,
suffixIconColor
,
suffix
,
suffix
,
suffixText
,
suffixText
,
suffixStyle
,
suffixStyle
,
...
@@ -3522,6 +3673,7 @@ class InputDecoration {
...
@@ -3522,6 +3673,7 @@ class InputDecoration {
String
toString
()
{
String
toString
()
{
final
List
<
String
>
description
=
<
String
>[
final
List
<
String
>
description
=
<
String
>[
if
(
icon
!=
null
)
'icon:
$icon
'
,
if
(
icon
!=
null
)
'icon:
$icon
'
,
if
(
iconColor
!=
null
)
'iconColor:
$iconColor
'
,
if
(
label
!=
null
)
'label:
$label
'
,
if
(
label
!=
null
)
'label:
$label
'
,
if
(
labelText
!=
null
)
'labelText: "
$labelText
"'
,
if
(
labelText
!=
null
)
'labelText: "
$labelText
"'
,
if
(
floatingLabelStyle
!=
null
)
'floatingLabelStyle: "
$floatingLabelStyle
"'
,
if
(
floatingLabelStyle
!=
null
)
'floatingLabelStyle: "
$floatingLabelStyle
"'
,
...
@@ -3537,11 +3689,13 @@ class InputDecoration {
...
@@ -3537,11 +3689,13 @@ class InputDecoration {
if
(
contentPadding
!=
null
)
'contentPadding:
$contentPadding
'
,
if
(
contentPadding
!=
null
)
'contentPadding:
$contentPadding
'
,
if
(
isCollapsed
)
'isCollapsed:
$isCollapsed
'
,
if
(
isCollapsed
)
'isCollapsed:
$isCollapsed
'
,
if
(
prefixIcon
!=
null
)
'prefixIcon:
$prefixIcon
'
,
if
(
prefixIcon
!=
null
)
'prefixIcon:
$prefixIcon
'
,
if
(
prefixIconColor
!=
null
)
'prefixIconColor:
$prefixIconColor
'
,
if
(
prefix
!=
null
)
'prefix:
$prefix
'
,
if
(
prefix
!=
null
)
'prefix:
$prefix
'
,
if
(
prefixText
!=
null
)
'prefixText:
$prefixText
'
,
if
(
prefixText
!=
null
)
'prefixText:
$prefixText
'
,
if
(
prefixStyle
!=
null
)
'prefixStyle:
$prefixStyle
'
,
if
(
prefixStyle
!=
null
)
'prefixStyle:
$prefixStyle
'
,
if
(
prefixIconConstraints
!=
null
)
'prefixIconConstraints:
$prefixIconConstraints
'
,
if
(
prefixIconConstraints
!=
null
)
'prefixIconConstraints:
$prefixIconConstraints
'
,
if
(
suffixIcon
!=
null
)
'suffixIcon:
$suffixIcon
'
,
if
(
suffixIcon
!=
null
)
'suffixIcon:
$suffixIcon
'
,
if
(
suffixIconColor
!=
null
)
'suffixIconColor:
$suffixIconColor
'
,
if
(
suffix
!=
null
)
'suffix:
$suffix
'
,
if
(
suffix
!=
null
)
'suffix:
$suffix
'
,
if
(
suffixText
!=
null
)
'suffixText:
$suffixText
'
,
if
(
suffixText
!=
null
)
'suffixText:
$suffixText
'
,
if
(
suffixStyle
!=
null
)
'suffixStyle:
$suffixStyle
'
,
if
(
suffixStyle
!=
null
)
'suffixStyle:
$suffixStyle
'
,
...
@@ -3596,8 +3750,11 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3596,8 +3750,11 @@ class InputDecorationTheme with Diagnosticable {
this
.
isDense
=
false
,
this
.
isDense
=
false
,
this
.
contentPadding
,
this
.
contentPadding
,
this
.
isCollapsed
=
false
,
this
.
isCollapsed
=
false
,
this
.
iconColor
,
this
.
prefixStyle
,
this
.
prefixStyle
,
this
.
prefixIconColor
,
this
.
suffixStyle
,
this
.
suffixStyle
,
this
.
suffixIconColor
,
this
.
counterStyle
,
this
.
counterStyle
,
this
.
filled
=
false
,
this
.
filled
=
false
,
this
.
fillColor
,
this
.
fillColor
,
...
@@ -3622,6 +3779,10 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3622,6 +3779,10 @@ class InputDecorationTheme with Diagnosticable {
/// When the [InputDecoration.labelText] is floating above the input field,
/// When the [InputDecoration.labelText] is floating above the input field,
/// the text uses the [floatingLabelStyle] instead.
/// 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
/// If null, defaults to a value derived from the base [TextStyle] for the
/// input field and the current [Theme].
/// input field and the current [Theme].
final
TextStyle
?
labelStyle
;
final
TextStyle
?
labelStyle
;
...
@@ -3632,10 +3793,18 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3632,10 +3793,18 @@ class InputDecorationTheme with Diagnosticable {
/// When the [InputDecoration.labelText] is on top of the input field, the
/// When the [InputDecoration.labelText] is on top of the input field, the
/// text uses the [labelStyle] instead.
/// 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].
/// If null, defaults to [labelStyle].
final
TextStyle
?
floatingLabelStyle
;
final
TextStyle
?
floatingLabelStyle
;
/// The style to use for [InputDecoration.helperText].
/// 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
;
final
TextStyle
?
helperStyle
;
/// The maximum number of lines the [InputDecoration.helperText] can occupy.
/// The maximum number of lines the [InputDecoration.helperText] can occupy.
...
@@ -3653,6 +3822,10 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3653,6 +3822,10 @@ class InputDecorationTheme with Diagnosticable {
/// The style to use for the [InputDecoration.hintText].
/// 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
/// Also used for the [InputDecoration.labelText] when the
/// [InputDecoration.labelText] is displayed on top of the input field (i.e.,
/// [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
/// at the same location on the screen where text may be entered in the input
...
@@ -3712,18 +3885,57 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3712,18 +3885,57 @@ class InputDecorationTheme with Diagnosticable {
/// [InputDecoration.errorText], or an [InputDecoration.icon].
/// [InputDecoration.errorText], or an [InputDecoration.icon].
final
bool
isCollapsed
;
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].
/// 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].
/// If null, defaults to the [hintStyle].
final
TextStyle
?
prefixStyle
;
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].
/// 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].
/// If null, defaults to the [hintStyle].
final
TextStyle
?
suffixStyle
;
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].
/// 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].
/// If null, defaults to the [helperStyle].
final
TextStyle
?
counterStyle
;
final
TextStyle
?
counterStyle
;
...
@@ -3890,6 +4102,10 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3890,6 +4102,10 @@ class InputDecorationTheme with Diagnosticable {
/// The shape of the border to draw around the decoration's container.
/// 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
/// 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
/// true and bordered per the [border]. It's the area adjacent to
/// [InputDecoration.icon] and above the widgets that contain
/// [InputDecoration.icon] and above the widgets that contain
...
@@ -3954,8 +4170,11 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3954,8 +4170,11 @@ class InputDecorationTheme with Diagnosticable {
bool
?
isDense
,
bool
?
isDense
,
EdgeInsetsGeometry
?
contentPadding
,
EdgeInsetsGeometry
?
contentPadding
,
bool
?
isCollapsed
,
bool
?
isCollapsed
,
Color
?
iconColor
,
TextStyle
?
prefixStyle
,
TextStyle
?
prefixStyle
,
Color
?
prefixIconColor
,
TextStyle
?
suffixStyle
,
TextStyle
?
suffixStyle
,
Color
?
suffixIconColor
,
TextStyle
?
counterStyle
,
TextStyle
?
counterStyle
,
bool
?
filled
,
bool
?
filled
,
Color
?
fillColor
,
Color
?
fillColor
,
...
@@ -3981,9 +4200,12 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -3981,9 +4200,12 @@ class InputDecorationTheme with Diagnosticable {
floatingLabelBehavior:
floatingLabelBehavior
??
this
.
floatingLabelBehavior
,
floatingLabelBehavior:
floatingLabelBehavior
??
this
.
floatingLabelBehavior
,
isDense:
isDense
??
this
.
isDense
,
isDense:
isDense
??
this
.
isDense
,
contentPadding:
contentPadding
??
this
.
contentPadding
,
contentPadding:
contentPadding
??
this
.
contentPadding
,
iconColor:
iconColor
,
isCollapsed:
isCollapsed
??
this
.
isCollapsed
,
isCollapsed:
isCollapsed
??
this
.
isCollapsed
,
prefixStyle:
prefixStyle
??
this
.
prefixStyle
,
prefixStyle:
prefixStyle
??
this
.
prefixStyle
,
prefixIconColor:
prefixIconColor
??
this
.
prefixIconColor
,
suffixStyle:
suffixStyle
??
this
.
suffixStyle
,
suffixStyle:
suffixStyle
??
this
.
suffixStyle
,
suffixIconColor:
suffixIconColor
??
this
.
suffixIconColor
,
counterStyle:
counterStyle
??
this
.
counterStyle
,
counterStyle:
counterStyle
??
this
.
counterStyle
,
filled:
filled
??
this
.
filled
,
filled:
filled
??
this
.
filled
,
fillColor:
fillColor
??
this
.
fillColor
,
fillColor:
fillColor
??
this
.
fillColor
,
...
@@ -4014,8 +4236,11 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -4014,8 +4236,11 @@ class InputDecorationTheme with Diagnosticable {
isDense
,
isDense
,
contentPadding
,
contentPadding
,
isCollapsed
,
isCollapsed
,
iconColor
,
prefixStyle
,
prefixStyle
,
prefixIconColor
,
suffixStyle
,
suffixStyle
,
suffixIconColor
,
counterStyle
,
counterStyle
,
filled
,
filled
,
fillColor
,
fillColor
,
...
@@ -4033,7 +4258,7 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -4033,7 +4258,7 @@ class InputDecorationTheme with Diagnosticable {
}
}
@override
@override
bool
operator
==(
Object
other
)
{
bool
operator
==(
Object
other
)
{
if
(
identical
(
this
,
other
))
if
(
identical
(
this
,
other
))
return
true
;
return
true
;
if
(
other
.
runtimeType
!=
runtimeType
)
if
(
other
.
runtimeType
!=
runtimeType
)
...
@@ -4049,8 +4274,11 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -4049,8 +4274,11 @@ class InputDecorationTheme with Diagnosticable {
&&
other
.
isDense
==
isDense
&&
other
.
isDense
==
isDense
&&
other
.
contentPadding
==
contentPadding
&&
other
.
contentPadding
==
contentPadding
&&
other
.
isCollapsed
==
isCollapsed
&&
other
.
isCollapsed
==
isCollapsed
&&
other
.
iconColor
==
iconColor
&&
other
.
prefixStyle
==
prefixStyle
&&
other
.
prefixStyle
==
prefixStyle
&&
other
.
prefixIconColor
==
prefixIconColor
&&
other
.
suffixStyle
==
suffixStyle
&&
other
.
suffixStyle
==
suffixStyle
&&
other
.
suffixIconColor
==
suffixIconColor
&&
other
.
counterStyle
==
counterStyle
&&
other
.
counterStyle
==
counterStyle
&&
other
.
floatingLabelBehavior
==
floatingLabelBehavior
&&
other
.
floatingLabelBehavior
==
floatingLabelBehavior
&&
other
.
filled
==
filled
&&
other
.
filled
==
filled
...
@@ -4083,7 +4311,10 @@ class InputDecorationTheme with Diagnosticable {
...
@@ -4083,7 +4311,10 @@ class InputDecorationTheme with Diagnosticable {
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'isDense'
,
isDense
,
defaultValue:
defaultTheme
.
isDense
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'isDense'
,
isDense
,
defaultValue:
defaultTheme
.
isDense
));
properties
.
add
(
DiagnosticsProperty
<
EdgeInsetsGeometry
>(
'contentPadding'
,
contentPadding
,
defaultValue:
defaultTheme
.
contentPadding
));
properties
.
add
(
DiagnosticsProperty
<
EdgeInsetsGeometry
>(
'contentPadding'
,
contentPadding
,
defaultValue:
defaultTheme
.
contentPadding
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'isCollapsed'
,
isCollapsed
,
defaultValue:
defaultTheme
.
isCollapsed
));
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
<
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
>(
'suffixStyle'
,
suffixStyle
,
defaultValue:
defaultTheme
.
suffixStyle
));
properties
.
add
(
DiagnosticsProperty
<
TextStyle
>(
'counterStyle'
,
counterStyle
,
defaultValue:
defaultTheme
.
counterStyle
));
properties
.
add
(
DiagnosticsProperty
<
TextStyle
>(
'counterStyle'
,
counterStyle
,
defaultValue:
defaultTheme
.
counterStyle
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'filled'
,
filled
,
defaultValue:
defaultTheme
.
filled
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'filled'
,
filled
,
defaultValue:
defaultTheme
.
filled
));
...
...
packages/flutter/lib/src/material/material_state.dart
View file @
64b0cfda
...
@@ -6,6 +6,8 @@ import 'package:flutter/foundation.dart';
...
@@ -6,6 +6,8 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'input_border.dart'
;
/// Interactive states that some of the Material widgets can take on when
/// Interactive states that some of the Material widgets can take on when
/// receiving input from the user.
/// receiving input from the user.
///
///
...
@@ -96,6 +98,9 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
...
@@ -96,6 +98,9 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
/// [Set] of [MaterialState]s, like [MaterialState.pressed],
/// [MaterialState.focused] and [MaterialState.hovered].
/// [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:
/// To use a [MaterialStateColor], you can either:
/// 1. Create a subclass of [MaterialStateColor] and implement the abstract `resolve` method.
/// 1. Create a subclass of [MaterialStateColor] and implement the abstract `resolve` method.
/// 2. Use [MaterialStateColor.resolveWith] and pass in a callback that
/// 2. Use [MaterialStateColor.resolveWith] and pass in a callback that
...
@@ -110,11 +115,6 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
...
@@ -110,11 +115,6 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
/// to provide a `defaultValue` to the super constructor, so that we can know
/// to provide a `defaultValue` to the super constructor, so that we can know
/// at compile-time what its default color is.
/// 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}
/// {@tool snippet}
///
///
/// This example defines a `MaterialStateColor` with a const constructor.
/// This example defines a `MaterialStateColor` with a const constructor.
...
@@ -391,6 +391,196 @@ abstract class MaterialStateOutlinedBorder extends OutlinedBorder implements Mat
...
@@ -391,6 +391,196 @@ abstract class MaterialStateOutlinedBorder extends OutlinedBorder implements Mat
OutlinedBorder
?
resolve
(
Set
<
MaterialState
>
states
);
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
/// Interface for classes that [resolve] to a value of type `T` based
/// on a widget's interactive "state", which is defined as a set
/// on a widget's interactive "state", which is defined as a set
/// of [MaterialState]s.
/// of [MaterialState]s.
...
...
packages/flutter/test/material/input_decorator_test.dart
View file @
64b0cfda
...
@@ -3642,6 +3642,110 @@ void main() {
...
@@ -3642,6 +3642,110 @@ void main() {
expect
(
decoration
.
constraints
,
const
BoxConstraints
(
minWidth:
10
,
maxWidth:
20
,
minHeight:
30
,
maxHeight:
40
));
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
{
testWidgets
(
'InputDecorator OutlineInputBorder fillColor is clipped by border'
,
(
WidgetTester
tester
)
async
{
// This is a regression test for https://github.com/flutter/flutter/issues/15742
// This is a regression test for https://github.com/flutter/flutter/issues/15742
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment