title: should Bloc pattern be used for flutter textfield and if yes how?
body: <p>So I'm new to Bloc but I understand how it works from previously working on native android development, but what I'm trying to understand is should it be implemented to create something like a TextField. Now, keep in mind that I am trying to reuse this TextField multiple times and I want the bloc pattern to dynamically validate the input but should I implement it completely <strong>like handle the text inputted by the user?</strong></p>
  <p><strong>what I've done is I've created a simple bloc pattern for the text field to handle the user input but it does not save the values from time to time it overwrites the previous value and the cursor keeps moving to the beginning of the text</strong></p>
  <pre><code>import 'dart:math';
  
  import 'package:competitionapp/data_model/events/formTextFieldEvent.dart';
  import 'package:competitionapp/data_model/states/formTextFieldState.dart';
  import 'package:flutter_bloc/flutter_bloc.dart';
  
  FormTextFieldBloc bloc = FormTextFieldBloc();
  
  class FormTextFieldBloc extends Bloc&lt;FormTextFieldEvent, FormTextFieldState&gt; {
    void onChanged(String value) {
      if (value == null || value.isEmpty)
  //      todo change to handle errors
        this.add(TextChangedEvent(&quot;error&quot;));
      else
        this.add(TextChangedEvent(value));
    }
  
    @override
    FormTextFieldState get initialState =&gt; FormTextFieldState.initState();
  
    @override
    Stream&lt;FormTextFieldState&gt; mapEventToState(FormTextFieldEvent event) async* {
      if (event is TextChangedEvent) {
        print(&quot;value received: ${event.eventText}&quot;);
        yield FormTextFieldState(event.eventText);
      }
    }
  }
  
  </code></pre>
  <pre><code>import 'package:competitionapp/data_model/blocModels/formTextFieldBloc.dart';
  import 'package:competitionapp/data_model/states/formTextFieldState.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_bloc/flutter_bloc.dart';
  
  // ignore: must_be_immutable
  class FormTextField extends StatelessWidget {
    final TextEditingController _controller;
    final String hint;
    final IconData iconData;
    final TextInputType inputType;
  
    final int maxLines;
    final int maxLength;
    final EdgeInsetsGeometry padding;
    final FormTextFieldBloc formTextFieldBloc;
  
    FormTextField(this._controller, this.formTextFieldBloc,
        {this.hint,
        this.iconData,
        this.inputType: TextInputType.text,
        this.maxLines: 1,
        this.maxLength,
        this.padding: const EdgeInsets.fromLTRB(15, 5, 15, 5)});
  
    @override
    Widget build(BuildContext context) {
      return Padding(
        padding: padding,
        child: BlocBuilder(
          bloc: formTextFieldBloc,
          builder: (context, FormTextFieldState state) {
            if (state.text.isNotEmpty &amp;&amp; state.text != null) {
              _controller.text = state.text;
              print(&quot;state text: ${state.text}&quot;);
            }
            return TextField(
              onChanged: (value) {
                print(value);
                formTextFieldBloc.onChanged(_controller.text);
              },
              onEditingComplete: (){
                print(_controller.text);
              },
              maxLength: maxLength ?? maxLength,
              maxLines: maxLines,
              keyboardType: inputType,
              controller: _controller,
              decoration: InputDecoration(
                contentPadding: EdgeInsets.symmetric(vertical: 10),
                border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                    borderSide: BorderSide(color: Colors.transparent, width: 0)),
                focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                    borderSide: BorderSide(color: Colors.transparent, width: 0)),
                enabledBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                    borderSide: BorderSide(color: Colors.transparent, width: 0)),
                hintText: hint,
                hintStyle:
                    Theme.of(context).textTheme.caption.copyWith(fontSize: 18),
                filled: true,
                fillColor: Theme.of(context).cardColor,
                prefixIcon: Icon(
                  iconData,
                  size: 16,
                  color: Theme.of(context).hintColor,
                ),
              ),
            );
          },
        ),
      );
    }
  }
  
  </code></pre>