|
@@ -0,0 +1,598 @@
|
|
1
|
+import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
|
2
|
+
|
|
3
|
+import 'package:flutter/gestures.dart';
|
|
4
|
+import 'package:flutter/material.dart';
|
|
5
|
+import 'package:flutter/services.dart';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+class PasswordTextField extends StatefulWidget {
|
|
9
|
+ const PasswordTextField({
|
|
10
|
+ super.key,
|
|
11
|
+ this.visibleIcon = Icons.remove_red_eye_outlined,
|
|
12
|
+ this.inVisibleIcon = Icons.remove_red_eye_outlined,
|
|
13
|
+ this.initialObscurity = false,
|
|
14
|
+ this.controller,
|
|
15
|
+ this.focusNode,
|
|
16
|
+ this.undoController,
|
|
17
|
+ this.decoration = const InputDecoration(),
|
|
18
|
+ this.keyboardType,
|
|
19
|
+ this.textInputAction,
|
|
20
|
+ this.textCapitalization = TextCapitalization.none,
|
|
21
|
+ this.style,
|
|
22
|
+ this.strutStyle,
|
|
23
|
+ this.textAlign = TextAlign.start,
|
|
24
|
+ this.textAlignVertical,
|
|
25
|
+ this.textDirection,
|
|
26
|
+ this.readOnly = false,
|
|
27
|
+ this.showCursor,
|
|
28
|
+ this.autofocus = false,
|
|
29
|
+ this.obscuringCharacter = '•',
|
|
30
|
+ this.autocorrect = true,
|
|
31
|
+ this.enableSuggestions = true,
|
|
32
|
+ this.maxLines = 1,
|
|
33
|
+ this.minLines,
|
|
34
|
+ this.expands = false,
|
|
35
|
+ this.maxLength,
|
|
36
|
+ this.maxLengthEnforcement,
|
|
37
|
+ this.onChanged,
|
|
38
|
+ this.onEditingComplete,
|
|
39
|
+ this.onSubmitted,
|
|
40
|
+ this.onAppPrivateCommand,
|
|
41
|
+ this.inputFormatters,
|
|
42
|
+ this.enabled,
|
|
43
|
+ this.cursorWidth = 2.0,
|
|
44
|
+ this.cursorHeight,
|
|
45
|
+ this.cursorRadius,
|
|
46
|
+ this.cursorOpacityAnimates,
|
|
47
|
+ this.cursorColor,
|
|
48
|
+ this.selectionHeightStyle = ui.BoxHeightStyle.tight,
|
|
49
|
+ this.selectionWidthStyle = ui.BoxWidthStyle.tight,
|
|
50
|
+ this.keyboardAppearance,
|
|
51
|
+ this.scrollPadding = const EdgeInsets.all(20.0),
|
|
52
|
+ this.dragStartBehavior = DragStartBehavior.start,
|
|
53
|
+ this.enableInteractiveSelection = true,
|
|
54
|
+ this.selectionControls,
|
|
55
|
+ this.onTap,
|
|
56
|
+ this.onTapOutside,
|
|
57
|
+ this.mouseCursor,
|
|
58
|
+ this.buildCounter,
|
|
59
|
+ this.scrollController,
|
|
60
|
+ this.scrollPhysics,
|
|
61
|
+ this.autofillHints = const <String>[],
|
|
62
|
+ this.contentInsertionConfiguration,
|
|
63
|
+ this.clipBehavior = Clip.hardEdge,
|
|
64
|
+ this.restorationId,
|
|
65
|
+ this.scribbleEnabled = true,
|
|
66
|
+ this.enableIMEPersonalizedLearning = true,
|
|
67
|
+ this.contextMenuBuilder,
|
|
68
|
+ this.canRequestFocus = true,
|
|
69
|
+ this.spellCheckConfiguration,
|
|
70
|
+ this.magnifierConfiguration,
|
|
71
|
+ });
|
|
72
|
+
|
|
73
|
+ /// Displaying toggle icon(show).
|
|
74
|
+ ///
|
|
75
|
+ /// Defaults is [Icons.visibility].
|
|
76
|
+ final IconData visibleIcon;
|
|
77
|
+
|
|
78
|
+ /// Displaying toggle icon(hide).
|
|
79
|
+ ///
|
|
80
|
+ /// Defaults is [Icons.visibility_off].
|
|
81
|
+ final IconData inVisibleIcon;
|
|
82
|
+
|
|
83
|
+ /// The obscure feature is enabled by default.
|
|
84
|
+ ///
|
|
85
|
+ /// Default is [false].
|
|
86
|
+ final bool initialObscurity;
|
|
87
|
+
|
|
88
|
+ /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
|
|
89
|
+ ///
|
|
90
|
+ /// {@macro flutter.widgets.magnifier.intro}
|
|
91
|
+ ///
|
|
92
|
+ /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
|
|
93
|
+ ///
|
|
94
|
+ /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier]
|
|
95
|
+ /// on Android, and builds nothing on all other platforms. If it is desired to
|
|
96
|
+ /// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled].
|
|
97
|
+ ///
|
|
98
|
+ /// {@tool dartpad}
|
|
99
|
+ /// This sample demonstrates how to customize the magnifier that this text field uses.
|
|
100
|
+ ///
|
|
101
|
+ /// ** See code in examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart **
|
|
102
|
+ /// {@end-tool}
|
|
103
|
+ final TextMagnifierConfiguration? magnifierConfiguration;
|
|
104
|
+
|
|
105
|
+ /// Controls the text being edited.
|
|
106
|
+ ///
|
|
107
|
+ /// If null, this widget will create its own [TextEditingController].
|
|
108
|
+ final TextEditingController? controller;
|
|
109
|
+
|
|
110
|
+ /// Defines the keyboard focus for this widget.
|
|
111
|
+ ///
|
|
112
|
+ /// The [focusNode] is a long-lived object that's typically managed by a
|
|
113
|
+ /// [StatefulWidget] parent. See [FocusNode] for more information.
|
|
114
|
+ ///
|
|
115
|
+ /// To give the keyboard focus to this widget, provide a [focusNode] and then
|
|
116
|
+ /// use the current [FocusScope] to request the focus:
|
|
117
|
+ ///
|
|
118
|
+ /// ```dart
|
|
119
|
+ /// FocusScope.of(context).requestFocus(myFocusNode);
|
|
120
|
+ /// ```
|
|
121
|
+ ///
|
|
122
|
+ /// This happens automatically when the widget is tapped.
|
|
123
|
+ ///
|
|
124
|
+ /// To be notified when the widget gains or loses the focus, add a listener
|
|
125
|
+ /// to the [focusNode]:
|
|
126
|
+ ///
|
|
127
|
+ /// ```dart
|
|
128
|
+ /// myFocusNode.addListener(() { print(myFocusNode.hasFocus); });
|
|
129
|
+ /// ```
|
|
130
|
+ ///
|
|
131
|
+ /// If null, this widget will create its own [FocusNode].
|
|
132
|
+ ///
|
|
133
|
+ /// ## Keyboard
|
|
134
|
+ ///
|
|
135
|
+ /// Requesting the focus will typically cause the keyboard to be shown
|
|
136
|
+ /// if it's not showing already.
|
|
137
|
+ ///
|
|
138
|
+ /// On Android, the user can hide the keyboard - without changing the focus -
|
|
139
|
+ /// with the system back button. They can restore the keyboard's visibility
|
|
140
|
+ /// by tapping on a text field. The user might hide the keyboard and
|
|
141
|
+ /// switch to a physical keyboard, or they might just need to get it
|
|
142
|
+ /// out of the way for a moment, to expose something it's
|
|
143
|
+ /// obscuring. In this case requesting the focus again will not
|
|
144
|
+ /// cause the focus to change, and will not make the keyboard visible.
|
|
145
|
+ ///
|
|
146
|
+ /// This widget builds an [EditableText] and will ensure that the keyboard is
|
|
147
|
+ /// showing when it is tapped by calling [EditableTextState.requestKeyboard()].
|
|
148
|
+ final FocusNode? focusNode;
|
|
149
|
+
|
|
150
|
+ /// The decoration to show around the text field.
|
|
151
|
+ ///
|
|
152
|
+ /// By default, draws a horizontal line under the text field but can be
|
|
153
|
+ /// configured to show an icon, label, hint text, and error text.
|
|
154
|
+ ///
|
|
155
|
+ /// Specify null to remove the decoration entirely (including the
|
|
156
|
+ /// extra padding introduced by the decoration to save space for the labels).
|
|
157
|
+ final InputDecoration decoration;
|
|
158
|
+
|
|
159
|
+ /// {@macro flutter.widgets.editableText.keyboardType}
|
|
160
|
+ final TextInputType? keyboardType;
|
|
161
|
+
|
|
162
|
+ /// The type of action button to use for the keyboard.
|
|
163
|
+ ///
|
|
164
|
+ /// Defaults to [TextInputAction.newline] if [keyboardType] is
|
|
165
|
+ /// [TextInputType.multiline] and [TextInputAction.done] otherwise.
|
|
166
|
+ final TextInputAction? textInputAction;
|
|
167
|
+
|
|
168
|
+ /// {@macro flutter.widgets.editableText.textCapitalization}
|
|
169
|
+ final TextCapitalization textCapitalization;
|
|
170
|
+
|
|
171
|
+ /// The style to use for the text being edited.
|
|
172
|
+ ///
|
|
173
|
+ /// This text style is also used as the base style for the [decoration].
|
|
174
|
+ ///
|
|
175
|
+ /// If null, defaults to the `titleMedium` text style from the current [Theme].
|
|
176
|
+ final TextStyle? style;
|
|
177
|
+
|
|
178
|
+ /// {@macro flutter.widgets.editableText.strutStyle}
|
|
179
|
+ final StrutStyle? strutStyle;
|
|
180
|
+
|
|
181
|
+ /// {@macro flutter.widgets.editableText.textAlign}
|
|
182
|
+ final TextAlign textAlign;
|
|
183
|
+
|
|
184
|
+ /// {@macro flutter.material.InputDecorator.textAlignVertical}
|
|
185
|
+ final TextAlignVertical? textAlignVertical;
|
|
186
|
+
|
|
187
|
+ /// {@macro flutter.widgets.editableText.textDirection}
|
|
188
|
+ final TextDirection? textDirection;
|
|
189
|
+
|
|
190
|
+ /// {@macro flutter.widgets.editableText.autofocus}
|
|
191
|
+ final bool autofocus;
|
|
192
|
+
|
|
193
|
+ /// {@macro flutter.widgets.editableText.obscuringCharacter}
|
|
194
|
+ final String obscuringCharacter;
|
|
195
|
+
|
|
196
|
+ /// {@macro flutter.widgets.editableText.autocorrect}
|
|
197
|
+ final bool autocorrect;
|
|
198
|
+
|
|
199
|
+ /// {@macro flutter.services.TextInputConfiguration.enableSuggestions}
|
|
200
|
+ final bool enableSuggestions;
|
|
201
|
+
|
|
202
|
+ /// {@macro flutter.widgets.editableText.maxLines}
|
|
203
|
+ /// * [expands], which determines whether the field should fill the height of
|
|
204
|
+ /// its parent.
|
|
205
|
+ final int? maxLines;
|
|
206
|
+
|
|
207
|
+ /// {@macro flutter.widgets.editableText.minLines}
|
|
208
|
+ /// * [expands], which determines whether the field should fill the height of
|
|
209
|
+ /// its parent.
|
|
210
|
+ final int? minLines;
|
|
211
|
+
|
|
212
|
+ /// {@macro flutter.widgets.editableText.expands}
|
|
213
|
+ final bool expands;
|
|
214
|
+
|
|
215
|
+ /// {@macro flutter.widgets.editableText.readOnly}
|
|
216
|
+ final bool readOnly;
|
|
217
|
+
|
|
218
|
+ /// {@macro flutter.widgets.editableText.showCursor}
|
|
219
|
+ final bool? showCursor;
|
|
220
|
+
|
|
221
|
+ /// The maximum number of characters (Unicode grapheme clusters) to allow in
|
|
222
|
+ /// the text field.
|
|
223
|
+ ///
|
|
224
|
+ /// If set, a character counter will be displayed below the
|
|
225
|
+ /// field showing how many characters have been entered. If set to a number
|
|
226
|
+ /// greater than 0, it will also display the maximum number allowed. If set
|
|
227
|
+ /// to [TextField.noMaxLength] then only the current character count is displayed.
|
|
228
|
+ ///
|
|
229
|
+ /// After [maxLength] characters have been input, additional input
|
|
230
|
+ /// is ignored, unless [maxLengthEnforcement] is set to
|
|
231
|
+ /// [MaxLengthEnforcement.none].
|
|
232
|
+ ///
|
|
233
|
+ /// The text field enforces the length with a [LengthLimitingTextInputFormatter],
|
|
234
|
+ /// which is evaluated after the supplied [inputFormatters], if any.
|
|
235
|
+ ///
|
|
236
|
+ /// This value must be either null, [TextField.noMaxLength], or greater than 0.
|
|
237
|
+ /// If null (the default) then there is no limit to the number of characters
|
|
238
|
+ /// that can be entered. If set to [TextField.noMaxLength], then no limit will
|
|
239
|
+ /// be enforced, but the number of characters entered will still be displayed.
|
|
240
|
+ ///
|
|
241
|
+ /// Whitespace characters (e.g. newline, space, tab) are included in the
|
|
242
|
+ /// character count.
|
|
243
|
+ ///
|
|
244
|
+ /// If [maxLengthEnforcement] is [MaxLengthEnforcement.none], then more than
|
|
245
|
+ /// [maxLength] characters may be entered, but the error counter and divider
|
|
246
|
+ /// will switch to the [decoration]'s [InputDecoration.errorStyle] when the
|
|
247
|
+ /// limit is exceeded.
|
|
248
|
+ ///
|
|
249
|
+ /// {@macro flutter.services.lengthLimitingTextInputFormatter.maxLength}
|
|
250
|
+ final int? maxLength;
|
|
251
|
+
|
|
252
|
+ /// Determines how the [maxLength] limit should be enforced.
|
|
253
|
+ ///
|
|
254
|
+ /// {@macro flutter.services.textFormatter.effectiveMaxLengthEnforcement}
|
|
255
|
+ ///
|
|
256
|
+ /// {@macro flutter.services.textFormatter.maxLengthEnforcement}
|
|
257
|
+ final MaxLengthEnforcement? maxLengthEnforcement;
|
|
258
|
+
|
|
259
|
+ /// {@macro flutter.widgets.editableText.onChanged}
|
|
260
|
+ ///
|
|
261
|
+ /// See also:
|
|
262
|
+ ///
|
|
263
|
+ /// * [inputFormatters], which are called before [onChanged]
|
|
264
|
+ /// runs and can validate and change ("format") the input value.
|
|
265
|
+ /// * [onEditingComplete], [onSubmitted]:
|
|
266
|
+ /// which are more specialized input change notifications.
|
|
267
|
+ final ValueChanged<String>? onChanged;
|
|
268
|
+
|
|
269
|
+ /// {@macro flutter.widgets.editableText.onEditingComplete}
|
|
270
|
+ final VoidCallback? onEditingComplete;
|
|
271
|
+
|
|
272
|
+ /// {@macro flutter.widgets.editableText.onSubmitted}
|
|
273
|
+ ///
|
|
274
|
+ /// See also:
|
|
275
|
+ ///
|
|
276
|
+ /// * [TextInputAction.next] and [TextInputAction.previous], which
|
|
277
|
+ /// automatically shift the focus to the next/previous focusable item when
|
|
278
|
+ /// the user is done editing.
|
|
279
|
+ final ValueChanged<String>? onSubmitted;
|
|
280
|
+
|
|
281
|
+ /// {@macro flutter.widgets.editableText.onAppPrivateCommand}
|
|
282
|
+ final AppPrivateCommandCallback? onAppPrivateCommand;
|
|
283
|
+
|
|
284
|
+ /// {@macro flutter.widgets.editableText.inputFormatters}
|
|
285
|
+ final List<TextInputFormatter>? inputFormatters;
|
|
286
|
+
|
|
287
|
+ /// If false the text field is "disabled": it ignores taps and its
|
|
288
|
+ /// [decoration] is rendered in grey.
|
|
289
|
+ ///
|
|
290
|
+ /// If non-null this property overrides the [decoration]'s
|
|
291
|
+ /// [InputDecoration.enabled] property.
|
|
292
|
+ final bool? enabled;
|
|
293
|
+
|
|
294
|
+ /// {@macro flutter.widgets.editableText.cursorWidth}
|
|
295
|
+ final double cursorWidth;
|
|
296
|
+
|
|
297
|
+ /// {@macro flutter.widgets.editableText.cursorHeight}
|
|
298
|
+ final double? cursorHeight;
|
|
299
|
+
|
|
300
|
+ /// {@macro flutter.widgets.editableText.cursorRadius}
|
|
301
|
+ final Radius? cursorRadius;
|
|
302
|
+
|
|
303
|
+ /// {@macro flutter.widgets.editableText.cursorOpacityAnimates}
|
|
304
|
+ final bool? cursorOpacityAnimates;
|
|
305
|
+
|
|
306
|
+ /// The color of the cursor.
|
|
307
|
+ ///
|
|
308
|
+ /// The cursor indicates the current location of text insertion point in
|
|
309
|
+ /// the field.
|
|
310
|
+ ///
|
|
311
|
+ /// If this is null it will default to the ambient
|
|
312
|
+ /// [DefaultSelectionStyle.cursorColor]. If that is null, and the
|
|
313
|
+ /// [ThemeData.platform] is [TargetPlatform.iOS] or [TargetPlatform.macOS]
|
|
314
|
+ /// it will use [CupertinoThemeData.primaryColor]. Otherwise it will use
|
|
315
|
+ /// the value of [ColorScheme.primary] of [ThemeData.colorScheme].
|
|
316
|
+ final Color? cursorColor;
|
|
317
|
+
|
|
318
|
+ /// Controls how tall the selection highlight boxes are computed to be.
|
|
319
|
+ ///
|
|
320
|
+ /// See [ui.BoxHeightStyle] for details on available styles.
|
|
321
|
+ final ui.BoxHeightStyle selectionHeightStyle;
|
|
322
|
+
|
|
323
|
+ /// Controls how wide the selection highlight boxes are computed to be.
|
|
324
|
+ ///
|
|
325
|
+ /// See [ui.BoxWidthStyle] for details on available styles.
|
|
326
|
+ final ui.BoxWidthStyle selectionWidthStyle;
|
|
327
|
+
|
|
328
|
+ /// The appearance of the keyboard.
|
|
329
|
+ ///
|
|
330
|
+ /// This setting is only honored on iOS devices.
|
|
331
|
+ ///
|
|
332
|
+ /// If unset, defaults to [ThemeData.brightness].
|
|
333
|
+ final Brightness? keyboardAppearance;
|
|
334
|
+
|
|
335
|
+ /// {@macro flutter.widgets.editableText.scrollPadding}
|
|
336
|
+ final EdgeInsets scrollPadding;
|
|
337
|
+
|
|
338
|
+ /// {@macro flutter.widgets.editableText.enableInteractiveSelection}
|
|
339
|
+ final bool enableInteractiveSelection;
|
|
340
|
+
|
|
341
|
+ /// {@macro flutter.widgets.editableText.selectionControls}
|
|
342
|
+ final TextSelectionControls? selectionControls;
|
|
343
|
+
|
|
344
|
+ /// {@macro flutter.widgets.scrollable.dragStartBehavior}
|
|
345
|
+ final DragStartBehavior dragStartBehavior;
|
|
346
|
+
|
|
347
|
+ /// {@macro flutter.widgets.editableText.selectionEnabled}
|
|
348
|
+ bool get selectionEnabled => enableInteractiveSelection;
|
|
349
|
+
|
|
350
|
+ /// {@template flutter.material.textfield.onTap}
|
|
351
|
+ /// Called for each distinct tap except for every second tap of a double tap.
|
|
352
|
+ ///
|
|
353
|
+ /// The text field builds a [GestureDetector] to handle input events like tap,
|
|
354
|
+ /// to trigger focus requests, to move the caret, adjust the selection, etc.
|
|
355
|
+ /// Handling some of those events by wrapping the text field with a competing
|
|
356
|
+ /// GestureDetector is problematic.
|
|
357
|
+ ///
|
|
358
|
+ /// To unconditionally handle taps, without interfering with the text field's
|
|
359
|
+ /// internal gesture detector, provide this callback.
|
|
360
|
+ ///
|
|
361
|
+ /// If the text field is created with [enabled] false, taps will not be
|
|
362
|
+ /// recognized.
|
|
363
|
+ ///
|
|
364
|
+ /// To be notified when the text field gains or loses the focus, provide a
|
|
365
|
+ /// [focusNode] and add a listener to that.
|
|
366
|
+ ///
|
|
367
|
+ /// To listen to arbitrary pointer events without competing with the
|
|
368
|
+ /// text field's internal gesture detector, use a [Listener].
|
|
369
|
+ /// {@endtemplate}
|
|
370
|
+ final GestureTapCallback? onTap;
|
|
371
|
+
|
|
372
|
+ /// {@macro flutter.widgets.editableText.onTapOutside}
|
|
373
|
+ ///
|
|
374
|
+ /// {@tool dartpad}
|
|
375
|
+ /// This example shows how to use a `TextFieldTapRegion` to wrap a set of
|
|
376
|
+ /// "spinner" buttons that increment and decrement a value in the [TextField]
|
|
377
|
+ /// without causing the text field to lose keyboard focus.
|
|
378
|
+ ///
|
|
379
|
+ /// This example includes a generic `SpinnerField<T>` class that you can copy
|
|
380
|
+ /// into your own project and customize.
|
|
381
|
+ ///
|
|
382
|
+ /// ** See code in examples/api/lib/widgets/tap_region/text_field_tap_region.0.dart **
|
|
383
|
+ /// {@end-tool}
|
|
384
|
+ ///
|
|
385
|
+ /// See also:
|
|
386
|
+ ///
|
|
387
|
+ /// * [TapRegion] for how the region group is determined.
|
|
388
|
+ final TapRegionCallback? onTapOutside;
|
|
389
|
+
|
|
390
|
+ /// The cursor for a mouse pointer when it enters or is hovering over the
|
|
391
|
+ /// widget.
|
|
392
|
+ ///
|
|
393
|
+ /// If [mouseCursor] is a [MaterialStateProperty<MouseCursor>],
|
|
394
|
+ /// [MaterialStateProperty.resolve] is used for the following [MaterialState]s:
|
|
395
|
+ ///
|
|
396
|
+ /// * [MaterialState.error].
|
|
397
|
+ /// * [MaterialState.hovered].
|
|
398
|
+ /// * [MaterialState.focused].
|
|
399
|
+ /// * [MaterialState.disabled].
|
|
400
|
+ ///
|
|
401
|
+ /// If this property is null, [MaterialStateMouseCursor.textable] will be used.
|
|
402
|
+ ///
|
|
403
|
+ /// The [mouseCursor] is the only property of [TextField] that controls the
|
|
404
|
+ /// appearance of the mouse pointer. All other properties related to "cursor"
|
|
405
|
+ /// stand for the text cursor, which is usually a blinking vertical line at
|
|
406
|
+ /// the editing position.
|
|
407
|
+ final MouseCursor? mouseCursor;
|
|
408
|
+
|
|
409
|
+ /// Callback that generates a custom [InputDecoration.counter] widget.
|
|
410
|
+ ///
|
|
411
|
+ /// See [InputCounterWidgetBuilder] for an explanation of the passed in
|
|
412
|
+ /// arguments. The returned widget will be placed below the line in place of
|
|
413
|
+ /// the default widget built when [InputDecoration.counterText] is specified.
|
|
414
|
+ ///
|
|
415
|
+ /// The returned widget will be wrapped in a [Semantics] widget for
|
|
416
|
+ /// accessibility, but it also needs to be accessible itself. For example,
|
|
417
|
+ /// if returning a Text widget, set the [Text.semanticsLabel] property.
|
|
418
|
+ ///
|
|
419
|
+ /// {@tool snippet}
|
|
420
|
+ /// ```dart
|
|
421
|
+ /// Widget counter(
|
|
422
|
+ /// BuildContext context,
|
|
423
|
+ /// {
|
|
424
|
+ /// required int currentLength,
|
|
425
|
+ /// required int? maxLength,
|
|
426
|
+ /// required bool isFocused,
|
|
427
|
+ /// }
|
|
428
|
+ /// ) {
|
|
429
|
+ /// return Text(
|
|
430
|
+ /// '$currentLength of $maxLength characters',
|
|
431
|
+ /// semanticsLabel: 'character count',
|
|
432
|
+ /// );
|
|
433
|
+ /// }
|
|
434
|
+ /// ```
|
|
435
|
+ /// {@end-tool}
|
|
436
|
+ ///
|
|
437
|
+ /// If buildCounter returns null, then no counter and no Semantics widget will
|
|
438
|
+ /// be created at all.
|
|
439
|
+ final InputCounterWidgetBuilder? buildCounter;
|
|
440
|
+
|
|
441
|
+ /// {@macro flutter.widgets.editableText.scrollPhysics}
|
|
442
|
+ final ScrollPhysics? scrollPhysics;
|
|
443
|
+
|
|
444
|
+ /// {@macro flutter.widgets.editableText.scrollController}
|
|
445
|
+ final ScrollController? scrollController;
|
|
446
|
+
|
|
447
|
+ /// {@macro flutter.widgets.editableText.autofillHints}
|
|
448
|
+ /// {@macro flutter.services.AutofillConfiguration.autofillHints}
|
|
449
|
+ final Iterable<String>? autofillHints;
|
|
450
|
+
|
|
451
|
+ /// {@macro flutter.material.Material.clipBehavior}
|
|
452
|
+ ///
|
|
453
|
+ /// Defaults to [Clip.hardEdge].
|
|
454
|
+ final Clip clipBehavior;
|
|
455
|
+
|
|
456
|
+ /// {@template flutter.material.textfield.restorationId}
|
|
457
|
+ /// Restoration ID to save and restore the state of the text field.
|
|
458
|
+ ///
|
|
459
|
+ /// If non-null, the text field will persist and restore its current scroll
|
|
460
|
+ /// offset and - if no [controller] has been provided - the content of the
|
|
461
|
+ /// text field. If a [controller] has been provided, it is the responsibility
|
|
462
|
+ /// of the owner of that controller to persist and restore it, e.g. by using
|
|
463
|
+ /// a [RestorableTextEditingController].
|
|
464
|
+ ///
|
|
465
|
+ /// The state of this widget is persisted in a [RestorationBucket] claimed
|
|
466
|
+ /// from the surrounding [RestorationScope] using the provided restoration ID.
|
|
467
|
+ ///
|
|
468
|
+ /// See also:
|
|
469
|
+ ///
|
|
470
|
+ /// * [RestorationManager], which explains how state restoration works in
|
|
471
|
+ /// Flutter.
|
|
472
|
+ /// {@endtemplate}
|
|
473
|
+ final String? restorationId;
|
|
474
|
+
|
|
475
|
+ /// {@macro flutter.widgets.editableText.scribbleEnabled}
|
|
476
|
+ final bool scribbleEnabled;
|
|
477
|
+
|
|
478
|
+ /// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
|
|
479
|
+ final bool enableIMEPersonalizedLearning;
|
|
480
|
+
|
|
481
|
+ /// {@macro flutter.widgets.editableText.contentInsertionConfiguration}
|
|
482
|
+ final ContentInsertionConfiguration? contentInsertionConfiguration;
|
|
483
|
+
|
|
484
|
+ /// {@macro flutter.widgets.EditableText.contextMenuBuilder}
|
|
485
|
+ ///
|
|
486
|
+ /// If not provided, will build a default menu based on the platform.
|
|
487
|
+ ///
|
|
488
|
+ /// See also:
|
|
489
|
+ ///
|
|
490
|
+ /// * [AdaptiveTextSelectionToolbar], which is built by default.
|
|
491
|
+ final EditableTextContextMenuBuilder? contextMenuBuilder;
|
|
492
|
+
|
|
493
|
+ /// Determine whether this text field can request the primary focus.
|
|
494
|
+ ///
|
|
495
|
+ /// Defaults to true. If false, the text field will not request focus
|
|
496
|
+ /// when tapped, or when its context menu is displayed. If false it will not
|
|
497
|
+ /// be possible to move the focus to the text field with tab key.
|
|
498
|
+ final bool canRequestFocus;
|
|
499
|
+
|
|
500
|
+ /// {@macro flutter.widgets.undoHistory.controller}
|
|
501
|
+ final UndoHistoryController? undoController;
|
|
502
|
+
|
|
503
|
+ /// {@macro flutter.widgets.EditableText.spellCheckConfiguration}
|
|
504
|
+ ///
|
|
505
|
+ /// If [SpellCheckConfiguration.misspelledTextStyle] is not specified in this
|
|
506
|
+ /// configuration, then [materialMisspelledTextStyle] is used by default.
|
|
507
|
+ final SpellCheckConfiguration? spellCheckConfiguration;
|
|
508
|
+
|
|
509
|
+ @override
|
|
510
|
+ State<PasswordTextField> createState() => _PasswordTextFieldState();
|
|
511
|
+}
|
|
512
|
+
|
|
513
|
+class _PasswordTextFieldState extends State<PasswordTextField> {
|
|
514
|
+ late bool _obscure;
|
|
515
|
+
|
|
516
|
+ @override
|
|
517
|
+ void initState() {
|
|
518
|
+ _obscure = widget.initialObscurity;
|
|
519
|
+
|
|
520
|
+ super.initState();
|
|
521
|
+ }
|
|
522
|
+
|
|
523
|
+ @override
|
|
524
|
+ Widget build(BuildContext context) {
|
|
525
|
+ return TextField(
|
|
526
|
+ obscureText: _obscure,
|
|
527
|
+ decoration: widget.decoration.copyWith(
|
|
528
|
+ suffixIcon: IconButton(
|
|
529
|
+ icon: Icon(
|
|
530
|
+ _obscure ? widget.inVisibleIcon : widget.visibleIcon,
|
|
531
|
+ size: 18, color: const Color(0xFFBBBBBB)
|
|
532
|
+ ),
|
|
533
|
+ onPressed: () {
|
|
534
|
+ setState(() {
|
|
535
|
+ _obscure = !_obscure;
|
|
536
|
+ });
|
|
537
|
+ },
|
|
538
|
+ ),
|
|
539
|
+ ),
|
|
540
|
+ controller: widget.controller,
|
|
541
|
+ focusNode: widget.focusNode,
|
|
542
|
+ undoController: widget.undoController,
|
|
543
|
+ keyboardType: widget.keyboardType,
|
|
544
|
+ textInputAction: widget.textInputAction,
|
|
545
|
+ textCapitalization: widget.textCapitalization,
|
|
546
|
+ style: widget.style,
|
|
547
|
+ strutStyle: widget.strutStyle,
|
|
548
|
+ textAlign: widget.textAlign,
|
|
549
|
+ textAlignVertical: widget.textAlignVertical,
|
|
550
|
+ textDirection: widget.textDirection,
|
|
551
|
+ readOnly: widget.readOnly,
|
|
552
|
+ showCursor: widget.showCursor,
|
|
553
|
+ autofocus: widget.autofocus,
|
|
554
|
+ obscuringCharacter: widget.obscuringCharacter,
|
|
555
|
+ autocorrect: widget.autocorrect,
|
|
556
|
+ enableSuggestions: widget.enableSuggestions,
|
|
557
|
+ maxLines: widget.maxLines,
|
|
558
|
+ minLines: widget.minLines,
|
|
559
|
+ expands: widget.expands,
|
|
560
|
+ maxLength: widget.maxLength,
|
|
561
|
+ maxLengthEnforcement: widget.maxLengthEnforcement,
|
|
562
|
+ onChanged: widget.onChanged,
|
|
563
|
+ onEditingComplete: widget.onEditingComplete,
|
|
564
|
+ onSubmitted: widget.onSubmitted,
|
|
565
|
+ onAppPrivateCommand: widget.onAppPrivateCommand,
|
|
566
|
+ inputFormatters: widget.inputFormatters,
|
|
567
|
+ enabled: widget.enabled,
|
|
568
|
+ cursorWidth: widget.cursorWidth,
|
|
569
|
+ cursorHeight: widget.cursorHeight,
|
|
570
|
+ cursorRadius: widget.cursorRadius,
|
|
571
|
+ cursorOpacityAnimates: widget.cursorOpacityAnimates,
|
|
572
|
+ cursorColor: widget.cursorColor,
|
|
573
|
+ selectionHeightStyle: widget.selectionHeightStyle,
|
|
574
|
+ selectionWidthStyle: widget.selectionWidthStyle,
|
|
575
|
+ keyboardAppearance: widget.keyboardAppearance,
|
|
576
|
+ scrollPadding: widget.scrollPadding,
|
|
577
|
+ dragStartBehavior: widget.dragStartBehavior,
|
|
578
|
+ enableInteractiveSelection: widget.enableInteractiveSelection,
|
|
579
|
+ selectionControls: widget.selectionControls,
|
|
580
|
+ onTap: widget.onTap,
|
|
581
|
+ onTapOutside: widget.onTapOutside,
|
|
582
|
+ mouseCursor: widget.mouseCursor,
|
|
583
|
+ buildCounter: widget.buildCounter,
|
|
584
|
+ scrollController: widget.scrollController,
|
|
585
|
+ scrollPhysics: widget.scrollPhysics,
|
|
586
|
+ autofillHints: widget.autofillHints,
|
|
587
|
+ contentInsertionConfiguration: widget.contentInsertionConfiguration,
|
|
588
|
+ clipBehavior: widget.clipBehavior,
|
|
589
|
+ restorationId: widget.restorationId,
|
|
590
|
+ scribbleEnabled: widget.scribbleEnabled,
|
|
591
|
+ enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning,
|
|
592
|
+ contextMenuBuilder: widget.contextMenuBuilder,
|
|
593
|
+ canRequestFocus: widget.canRequestFocus,
|
|
594
|
+ spellCheckConfiguration: widget.spellCheckConfiguration,
|
|
595
|
+ magnifierConfiguration: widget.magnifierConfiguration,
|
|
596
|
+ );
|
|
597
|
+ }
|
|
598
|
+}
|