123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
- import 'package:flutter/gestures.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:lszlgl/widget/password_textfield.dart';
- /// A [FormField] that contains a [PasswordTextField].
- /// If you want to see the details of the API, check the [TextFormField].
- ///
- /// It has almost the same API as [TextFormField], so it can be replaced.
- class PasswordTextFormField extends FormField<String> {
- /// Creates a [FormField] that contains a [PasswordTextField].
- PasswordTextFormField({
- super.key,
- IconData visibleIcon = Icons.remove_red_eye_outlined,
- IconData inVisibleIcon = Icons.remove_red_eye_outlined,
- bool initialObscurity = true,
- this.controller,
- String? initialValue,
- FocusNode? focusNode,
- InputDecoration? decoration = const InputDecoration(),
- TextInputType? keyboardType,
- TextCapitalization textCapitalization = TextCapitalization.none,
- TextInputAction? textInputAction,
- TextStyle? style,
- StrutStyle? strutStyle,
- TextDirection? textDirection,
- TextAlign textAlign = TextAlign.start,
- TextAlignVertical? textAlignVertical,
- bool autofocus = false,
- bool readOnly = false,
- bool? showCursor,
- String obscuringCharacter = '•',
- bool obscureText = false,
- bool autocorrect = true,
- SmartDashesType? smartDashesType,
- SmartQuotesType? smartQuotesType,
- bool enableSuggestions = true,
- MaxLengthEnforcement? maxLengthEnforcement,
- int? maxLines = 1,
- int? minLines,
- bool expands = false,
- int? maxLength,
- ValueChanged<String>? onChanged,
- GestureTapCallback? onTap,
- TapRegionCallback? onTapOutside,
- VoidCallback? onEditingComplete,
- ValueChanged<String>? onFieldSubmitted,
- super.onSaved,
- super.validator,
- List<TextInputFormatter>? inputFormatters,
- bool? enabled,
- double cursorWidth = 2.0,
- double? cursorHeight,
- Radius? cursorRadius,
- Color? cursorColor,
- Brightness? keyboardAppearance,
- EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
- bool? enableInteractiveSelection,
- TextSelectionControls? selectionControls,
- InputCounterWidgetBuilder? buildCounter,
- ScrollPhysics? scrollPhysics,
- Iterable<String>? autofillHints,
- AutovalidateMode? autovalidateMode,
- ScrollController? scrollController,
- super.restorationId,
- bool enableIMEPersonalizedLearning = true,
- MouseCursor? mouseCursor,
- EditableTextContextMenuBuilder? contextMenuBuilder =
- _defaultContextMenuBuilder,
- SpellCheckConfiguration? spellCheckConfiguration,
- TextMagnifierConfiguration? magnifierConfiguration,
- UndoHistoryController? undoController,
- AppPrivateCommandCallback? onAppPrivateCommand,
- bool? cursorOpacityAnimates,
- ui.BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight,
- ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight,
- DragStartBehavior dragStartBehavior = DragStartBehavior.start,
- ContentInsertionConfiguration? contentInsertionConfiguration,
- Clip clipBehavior = Clip.hardEdge,
- bool scribbleEnabled = true,
- bool canRequestFocus = true,
- }) : super(
- initialValue:
- controller != null ? controller.text : (initialValue ?? ''),
- enabled: enabled ?? decoration?.enabled ?? true,
- autovalidateMode: autovalidateMode ?? AutovalidateMode.disabled,
- builder: (FormFieldState<String> field) {
- final _PasswordTextFormFieldState state =
- field as _PasswordTextFormFieldState;
- final InputDecoration effectiveDecoration = (decoration ??
- const InputDecoration())
- .applyDefaults(Theme.of(field.context).inputDecorationTheme);
- void onChangedHandler(String value) {
- field.didChange(value);
- if (onChanged != null) {
- onChanged(value);
- }
- }
- return UnmanagedRestorationScope(
- bucket: field.bucket,
- child: PasswordTextField(
- visibleIcon: visibleIcon,
- inVisibleIcon: inVisibleIcon,
- initialObscurity: initialObscurity,
- restorationId: restorationId,
- controller: state._effectiveController,
- focusNode: focusNode,
- decoration:
- effectiveDecoration.copyWith(errorText: field.errorText),
- keyboardType: keyboardType,
- textInputAction: textInputAction,
- style: style,
- strutStyle: strutStyle,
- textAlign: textAlign,
- textAlignVertical: textAlignVertical,
- textDirection: textDirection,
- textCapitalization: textCapitalization,
- autofocus: autofocus,
- readOnly: readOnly,
- showCursor: showCursor,
- obscuringCharacter: obscuringCharacter,
- autocorrect: autocorrect,
- enableSuggestions: enableSuggestions,
- maxLengthEnforcement: maxLengthEnforcement,
- maxLines: maxLines,
- minLines: minLines,
- expands: expands,
- maxLength: maxLength,
- onChanged: onChangedHandler,
- onTap: onTap,
- onTapOutside: onTapOutside,
- onEditingComplete: onEditingComplete,
- onSubmitted: onFieldSubmitted,
- inputFormatters: inputFormatters,
- enabled: enabled ?? decoration?.enabled ?? true,
- cursorWidth: cursorWidth,
- cursorHeight: cursorHeight,
- cursorRadius: cursorRadius,
- cursorColor: cursorColor,
- scrollPadding: scrollPadding,
- scrollPhysics: scrollPhysics,
- keyboardAppearance: keyboardAppearance,
- enableInteractiveSelection:
- enableInteractiveSelection ?? (!obscureText || !readOnly),
- selectionControls: selectionControls,
- buildCounter: buildCounter,
- autofillHints: autofillHints,
- scrollController: scrollController,
- enableIMEPersonalizedLearning: enableIMEPersonalizedLearning,
- mouseCursor: mouseCursor,
- contextMenuBuilder: contextMenuBuilder,
- spellCheckConfiguration: spellCheckConfiguration,
- magnifierConfiguration: magnifierConfiguration,
- undoController: undoController,
- onAppPrivateCommand: onAppPrivateCommand,
- cursorOpacityAnimates: cursorOpacityAnimates,
- selectionHeightStyle: selectionHeightStyle,
- selectionWidthStyle: selectionWidthStyle,
- dragStartBehavior: dragStartBehavior,
- contentInsertionConfiguration: contentInsertionConfiguration,
- clipBehavior: clipBehavior,
- scribbleEnabled: scribbleEnabled,
- canRequestFocus: canRequestFocus,
- ),
- );
- },
- );
- /// Controls the text being edited.
- ///
- /// If null, this widget will create its own [TextEditingController] and
- /// initialize its [TextEditingController.text] with [initialValue].
- final TextEditingController? controller;
- static Widget _defaultContextMenuBuilder(
- BuildContext context, EditableTextState editableTextState) {
- return AdaptiveTextSelectionToolbar.editableText(
- editableTextState: editableTextState,
- );
- }
- @override
- FormFieldState<String> createState() => _PasswordTextFormFieldState();
- }
- /// see [TextFormField] & [_TextFormFieldState]
- class _PasswordTextFormFieldState extends FormFieldState<String> {
- RestorableTextEditingController? _controller;
- TextEditingController get _effectiveController =>
- _textFormField.controller ?? _controller!.value;
- PasswordTextFormField get _textFormField =>
- super.widget as PasswordTextFormField;
- @override
- void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
- super.restoreState(oldBucket, initialRestore);
- if (_controller != null) {
- _registerController();
- }
- // Make sure to update the internal [FormFieldState] value to sync up with
- // text editing controller value.
- setValue(_effectiveController.text);
- }
- void _registerController() {
- assert(_controller != null);
- registerForRestoration(_controller!, 'controller');
- }
- void _createLocalController([TextEditingValue? value]) {
- assert(_controller == null);
- _controller = value == null
- ? RestorableTextEditingController()
- : RestorableTextEditingController.fromValue(value);
- if (!restorePending) {
- _registerController();
- }
- }
- @override
- void initState() {
- super.initState();
- if (_textFormField.controller == null) {
- _createLocalController(widget.initialValue != null
- ? TextEditingValue(text: widget.initialValue!)
- : null);
- } else {
- _textFormField.controller!.addListener(_handleControllerChanged);
- }
- }
- @override
- void didUpdateWidget(PasswordTextFormField oldWidget) {
- super.didUpdateWidget(oldWidget);
- if (_textFormField.controller != oldWidget.controller) {
- oldWidget.controller?.removeListener(_handleControllerChanged);
- _textFormField.controller?.addListener(_handleControllerChanged);
- if (oldWidget.controller != null && _textFormField.controller == null) {
- _createLocalController(oldWidget.controller!.value);
- }
- if (_textFormField.controller != null) {
- setValue(_textFormField.controller!.text);
- if (oldWidget.controller == null) {
- unregisterFromRestoration(_controller!);
- _controller!.dispose();
- _controller = null;
- }
- }
- }
- }
- @override
- void dispose() {
- _textFormField.controller?.removeListener(_handleControllerChanged);
- _controller?.dispose();
- super.dispose();
- }
- @override
- void didChange(String? value) {
- super.didChange(value);
- if (_effectiveController.text != value) {
- _effectiveController.text = value ?? '';
- }
- }
- @override
- void reset() {
- // setState will be called in the superclass, so even though state is being
- // manipulated, no setState call is needed here.
- _effectiveController.text = widget.initialValue ?? '';
- super.reset();
- }
- void _handleControllerChanged() {
- // Suppress changes that originated from within this class.
- //
- // In the case where a controller has been passed in to this widget, we
- // register this change listener. In these cases, we'll also receive change
- // notifications for changes originating from within this class -- for
- // example, the reset() method. In such cases, the FormField value will
- // already have been set.
- if (_effectiveController.text != value) {
- didChange(_effectiveController.text);
- }
- }
- }
|