@@ -37,6 +37,10 @@ class InputDecoration {
37
37
this .errorStyle,
38
38
this .isDense: false ,
39
39
this .hideDivider: false ,
40
+ this .prefixText,
41
+ this .prefixStyle,
42
+ this .suffixText,
43
+ this .suffixStyle,
40
44
}) : isCollapsed = false ;
41
45
42
46
/// Creates a decoration that is the same size as the input field.
@@ -55,7 +59,11 @@ class InputDecoration {
55
59
errorStyle = null ,
56
60
isDense = false ,
57
61
isCollapsed = true ,
58
- hideDivider = true ;
62
+ hideDivider = true ,
63
+ prefixText = null ,
64
+ prefixStyle = null ,
65
+ suffixText = null ,
66
+ suffixStyle = null ;
59
67
60
68
/// An icon to show before the input field.
61
69
///
@@ -108,7 +116,7 @@ class InputDecoration {
108
116
/// If non-null the divider, that appears below the input field is red.
109
117
final String errorText;
110
118
111
- /// The style to use for the [errorText.
119
+ /// The style to use for the [errorText] .
112
120
///
113
121
/// If null, defaults of a value derived from the base [TextStyle] for the
114
122
/// input field and the current [Theme] .
@@ -133,6 +141,28 @@ class InputDecoration {
133
141
/// Defaults to false.
134
142
final bool hideDivider;
135
143
144
+ /// Optional text prefix to place on the line before the input.
145
+ ///
146
+ /// Uses the [prefixStyle] . Uses [hintStyle] if [prefixStyle] isn't
147
+ /// specified. Prefix is not returned as part of the input.
148
+ final String prefixText;
149
+
150
+ /// The style to use for the [prefixText] .
151
+ ///
152
+ /// If null, defaults to the [hintStyle] .
153
+ final TextStyle prefixStyle;
154
+
155
+ /// Optional text suffix to place on the line after the input.
156
+ ///
157
+ /// Uses the [suffixStyle] . Uses [hintStyle] if [suffixStyle] isn't
158
+ /// specified. Suffix is not returned as part of the input.
159
+ final String suffixText;
160
+
161
+ /// The style to use for the [suffixText] .
162
+ ///
163
+ /// If null, defaults to the [hintStyle] .
164
+ final TextStyle suffixStyle;
165
+
136
166
/// Creates a copy of this input decoration but with the given fields replaced
137
167
/// with the new values.
138
168
///
@@ -147,6 +177,10 @@ class InputDecoration {
147
177
TextStyle errorStyle,
148
178
bool isDense,
149
179
bool hideDivider,
180
+ String prefixText,
181
+ TextStyle prefixStyle,
182
+ String suffixText,
183
+ TextStyle suffixStyle,
150
184
}) {
151
185
return new InputDecoration (
152
186
icon: icon ?? this .icon,
@@ -158,6 +192,10 @@ class InputDecoration {
158
192
errorStyle: errorStyle ?? this .errorStyle,
159
193
isDense: isDense ?? this .isDense,
160
194
hideDivider: hideDivider ?? this .hideDivider,
195
+ prefixText: prefixText ?? this .prefixText,
196
+ prefixStyle: prefixStyle ?? this .prefixStyle,
197
+ suffixText: suffixText ?? this .suffixText,
198
+ suffixStyle: suffixStyle ?? this .suffixStyle,
161
199
);
162
200
}
163
201
@@ -177,7 +215,11 @@ class InputDecoration {
177
215
&& typedOther.errorStyle == errorStyle
178
216
&& typedOther.isDense == isDense
179
217
&& typedOther.isCollapsed == isCollapsed
180
- && typedOther.hideDivider == hideDivider;
218
+ && typedOther.hideDivider == hideDivider
219
+ && typedOther.prefixText == prefixText
220
+ && typedOther.prefixStyle == prefixStyle
221
+ && typedOther.suffixText == suffixText
222
+ && typedOther.suffixStyle == suffixStyle;
181
223
}
182
224
183
225
@override
@@ -193,6 +235,10 @@ class InputDecoration {
193
235
isDense,
194
236
isCollapsed,
195
237
hideDivider,
238
+ prefixText,
239
+ prefixStyle,
240
+ suffixText,
241
+ suffixStyle,
196
242
);
197
243
}
198
244
@@ -213,6 +259,14 @@ class InputDecoration {
213
259
description.add ('isCollapsed: $isCollapsed ' );
214
260
if (hideDivider)
215
261
description.add ('hideDivider: $hideDivider ' );
262
+ if (prefixText != null )
263
+ description.add ('prefixText: $prefixText ' );
264
+ if (prefixStyle != null )
265
+ description.add ('prefixStyle: $prefixStyle ' );
266
+ if (suffixText != null )
267
+ description.add ('suffixText: $suffixText ' );
268
+ if (suffixStyle != null )
269
+ description.add ('suffixStyle: $suffixStyle ' );
216
270
return 'InputDecoration(${description .join (', ' )})' ;
217
271
}
218
272
}
@@ -293,7 +347,7 @@ class InputDecorator extends StatelessWidget {
293
347
return themeData.hintColor;
294
348
}
295
349
296
- Widget _buildContent (Color borderColor, double topPadding, bool isDense) {
350
+ Widget _buildContent (Color borderColor, double topPadding, bool isDense, Widget inputChild ) {
297
351
final double bottomPadding = isDense ? 8.0 : 1.0 ;
298
352
const double bottomBorder = 2.0 ;
299
353
final double bottomHeight = isDense ? 14.0 : 18.0 ;
@@ -305,7 +359,7 @@ class InputDecorator extends StatelessWidget {
305
359
return new Container (
306
360
margin: margin + const EdgeInsets .only (bottom: bottomBorder),
307
361
padding: padding,
308
- child: child ,
362
+ child: inputChild ,
309
363
);
310
364
}
311
365
@@ -322,7 +376,7 @@ class InputDecorator extends StatelessWidget {
322
376
),
323
377
),
324
378
),
325
- child: child ,
379
+ child: inputChild ,
326
380
);
327
381
}
328
382
@@ -348,7 +402,7 @@ class InputDecorator extends StatelessWidget {
348
402
349
403
final List <Widget > stackChildren = < Widget > [];
350
404
351
- // If we're not focused, there's not value, and labelText was provided,
405
+ // If we're not focused, there's no value, and labelText was provided,
352
406
// then the label appears where the hint would. And we will not show
353
407
// the hintText.
354
408
final bool hasInlineLabel = ! isFocused && labelText != null && isEmpty;
@@ -402,11 +456,33 @@ class InputDecorator extends StatelessWidget {
402
456
);
403
457
}
404
458
459
+ Widget inputChild;
460
+ if (! hasInlineLabel && (! isEmpty || hintText == null ) &&
461
+ (decoration? .prefixText != null || decoration? .suffixText != null )) {
462
+ final List <Widget > rowContents = < Widget > [];
463
+ if (decoration.prefixText != null ) {
464
+ rowContents.add (
465
+ new Text (decoration.prefixText,
466
+ style: decoration.prefixStyle ?? hintStyle)
467
+ );
468
+ }
469
+ rowContents.add (new Expanded (child: child));
470
+ if (decoration.suffixText != null ) {
471
+ rowContents.add (
472
+ new Text (decoration.suffixText,
473
+ style: decoration.suffixStyle ?? hintStyle)
474
+ );
475
+ }
476
+ inputChild = new Row (children: rowContents);
477
+ } else {
478
+ inputChild = child;
479
+ }
480
+
405
481
if (isCollapsed) {
406
- stackChildren.add (child );
482
+ stackChildren.add (inputChild );
407
483
} else {
408
484
final Color borderColor = errorText == null ? activeColor : themeData.errorColor;
409
- stackChildren.add (_buildContent (borderColor, topPadding, isDense));
485
+ stackChildren.add (_buildContent (borderColor, topPadding, isDense, inputChild ));
410
486
}
411
487
412
488
if (! isDense && errorText != null ) {
0 commit comments