Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter onChanged and onSaved together for Text Inputs

I've been trying to implement a small form in Flutter and found that the onChanged and onSaved events are not available together on either of the 2 TextInput widgets.

onChanged is defined in TextField widget and onSaved is defined in TextFormField widget. One workaround is to use the TextEditingController to watch for changes but that adds a bunch of additional lines of code to add listeners, remove listeners and dispose. Is there a better solution to address this issue?

like image 880
Abin Avatar asked Jul 26 '18 11:07

Abin


1 Answers

You can create your own widget to support that method, like this :

    import 'package:flutter/material.dart';

    class MyTextField extends StatefulWidget {
      final Key key;
      final String initialValue;
      final FocusNode focusNode;
      final InputDecoration decoration;
      final TextInputType keyboardType;
      final TextInputAction textInputAction;
      final TextStyle style;
      final TextAlign textAlign;
      final bool autofocus;
      final bool obscureText;
      final bool autocorrect;
      final bool autovalidate;
      final bool maxLengthEnforced;
      final int maxLines;
      final int maxLength;
      final VoidCallback onEditingComplete;
      final ValueChanged<String> onFieldSubmitted;
      final FormFieldSetter<String> onSaved;
      final FormFieldValidator<String> validator;
      final bool enabled;
      final Brightness keyboardAppearance;
      final EdgeInsets scrollPadding;
      final ValueChanged<String> onChanged;

      MyTextField(
          {this.key,
          this.initialValue,
          this.focusNode,
          this.decoration = const InputDecoration(),
          this.keyboardType = TextInputType.text,
          this.textInputAction = TextInputAction.done,
          this.style,
          this.textAlign = TextAlign.start,
          this.autofocus = false,
          this.obscureText = false,
          this.autocorrect = true,
          this.autovalidate = false,
          this.maxLengthEnforced = true,
          this.maxLines = 1,
          this.maxLength,
          this.onEditingComplete,
          this.onFieldSubmitted,
          this.onSaved,
          this.validator,
          this.enabled,
          this.keyboardAppearance,
          this.scrollPadding = const EdgeInsets.all(20.0),
          this.onChanged});

      @override
      _MyTextFieldState createState() => _MyTextFieldState();
    }

    class _MyTextFieldState extends State<MyTextField> {
      final TextEditingController _controller = new TextEditingController();

      _onChangedValue() {
        if (widget.onChanged != null) {
          widget.onChanged(_controller.text);
        }
      }

      @override
      void initState() {
        _controller.addListener(_onChangedValue);
        super.initState();
      }

      @override
      void dispose() {
        _controller.removeListener(_onChangedValue);
        _controller.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return TextFormField(
          key: widget.key,
          controller: _controller,
          initialValue: widget.initialValue,
          focusNode: widget.focusNode,
          decoration: widget.decoration,
          keyboardType: widget.keyboardType,
          textInputAction: widget.textInputAction,
          style: widget.style,
          textAlign: widget.textAlign,
          autofocus: widget.autofocus,
          obscureText: widget.obscureText,
          autocorrect: widget.autocorrect,
          autovalidate: widget.autovalidate,
          maxLengthEnforced: widget.maxLengthEnforced,
          maxLines: widget.maxLines,
          onEditingComplete: widget.onEditingComplete,
          onFieldSubmitted: widget.onFieldSubmitted,
          onSaved: widget.onSaved,
          validator: widget.validator,
          enabled: widget.enabled,
          keyboardAppearance: widget.keyboardAppearance,
          scrollPadding: widget.scrollPadding,
        );
      }
    }

And include it in your page:

    Padding(
              padding: EdgeInsets.all(20.0),
              child: Center(child: MyTextField(
                onChanged: (value) {
                  print("testing onchanged $value");
                },
              )),
            )
like image 125
diegoveloper Avatar answered Sep 19 '22 12:09

diegoveloper