title: TextEditingController previous state is not getting disposed in Flutter
body: <p>I am using my own custom TextEditingController to add text to a <code>TextField</code>. I am disposing the <code>TextEditingController</code> in the <code>dispose()</code> method. Problem is when I enter some text in the TextField and just go back to previous screen and again come back. The text remains in the TextField which I don't want it to happen. I want to get it cleared as soon as the screen is popped off from the stack. How can I solve this?</p>
  
  <pre><code>class AddGoalsState extends State&lt;AddGoalScreen&gt; {
    GoalsBloc _bloc;
    TextEditingController myController = TextEditingController();
  
    @override
    void didChangeDependencies() {
      super.didChangeDependencies();
      _bloc = GoalsBlocProvider.of(context);
    }
  
    @override
    void dispose() {
      myController.dispose();
      _bloc.dispose();
      super.dispose();
    }
    Future&lt;bool&gt; _onWillPop(){
      Navigator.pop(context, false);
      return Future.value(false);
    }
    @override
    Widget build(BuildContext context) {
      return WillPopScope(
        onWillPop: _onWillPop,
        child: Scaffold(
          appBar: AppBar(
            title: Text(
              "Add Goal",
              style: TextStyle(color: Colors.black),
            ),
            backgroundColor: Colors.amber,
            elevation: 0.0,
          ),
          body: Container(
            padding: EdgeInsets.all(16.0),
            alignment: Alignment(0.0, 0.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: &lt;Widget&gt;[
                nameField(),
                Container(margin: EdgeInsets.only(top: 5.0, bottom: 5.0)),
                goalField(),
                Container(margin: EdgeInsets.only(top: 5.0, bottom: 5.0)),
                buttons(),
              ],
            ),
          ),
        ),
      );
    }
  
    Widget goalField() {
      return StreamBuilder(
          stream: _bloc.goalMessage,
          builder: (BuildContext context, AsyncSnapshot&lt;String&gt; snapshot) {
            myController.value = myController.value.copyWith(text: snapshot.data);
            return TextField(
              controller: myController,
              keyboardType: TextInputType.multiline,
              maxLines: 3,
              onChanged: _bloc.changeGoalMessage,
              decoration: InputDecoration(
                  hintText: "Enter your goal here", errorText: snapshot.error),
            );
          });
    }
  </code></pre>
  
  <p>My BLoC class:</p>
  
  <pre><code>class GoalsBloc {
    final _repository = Repository();
    final _title = BehaviorSubject&lt;String&gt;();
    final _goalMessage = BehaviorSubject&lt;String&gt;();
    final _showProgress = BehaviorSubject&lt;bool&gt;();
  
    Observable&lt;String&gt; get name =&gt; _title.stream.transform(_validateName);
  
    Observable&lt;String&gt; get goalMessage =&gt;
        _goalMessage.stream.transform(_validateMessage);
  
    Observable&lt;bool&gt; get showProgress =&gt; _showProgress.stream;
  
    Function(String) get changeName =&gt; _title.sink.add;
  
    Function(String) get changeGoalMessage =&gt; _goalMessage.sink.add;
  
    final _validateMessage = StreamTransformer&lt;String, String&gt;.fromHandlers(
        handleData: (goalMessage, sink) {
      if (goalMessage.length &gt; 10) {
        sink.add(goalMessage);
      } else {
        sink.addError(StringConstant.goalValidateMessage);
      }
    });
  
    final _validateName = StreamTransformer&lt;String, String&gt;.fromHandlers(
        handleData: (String name, sink) {
      if (RegExp(r'[!@#&lt;&gt;?":_`~;[\]\\|=+)(*&amp;^%0-9-]').hasMatch(name)) {
        sink.addError(StringConstant.nameValidateMessage);
      } else {
        sink.add(name);
      }
    });
  
    void submit(String email) {
      _showProgress.sink.add(true);
      _repository
          .uploadGoal(email, _title.value, _goalMessage.value)
          .then((value) {
        _showProgress.sink.add(false);
      });
    }
  
    void extractText(var image) {
      _repository.extractText(image).then((text) {
        _goalMessage.sink.add(text);
      });
    }
  
    Stream&lt;DocumentSnapshot&gt; myGoalsList(String email) {
      return _repository.myGoalList(email);
    }
  
    Stream&lt;QuerySnapshot&gt; othersGoalList() {
      return _repository.othersGoalList();
    }
  
    //dispose all open sink
    void dispose() async {
      await _goalMessage.drain();
      _goalMessage.close();
      await _title.drain();
      _title.close();
      await _showProgress.drain();
      _showProgress.close();
    }
  
    //Convert map to goal list
    List mapToList({DocumentSnapshot doc, List&lt;DocumentSnapshot&gt; docList}) {
      if (docList != null) {
        List&lt;OtherGoal&gt; goalList = [];
        docList.forEach((document) {
          String email = document.data[StringConstant.emailField];
          Map&lt;String, String&gt; goals =
              document.data[StringConstant.goalField] != null
                  ? document.data[StringConstant.goalField].cast&lt;String, String&gt;()
                  : null;
          if (goals != null) {
            goals.forEach((title, message) {
              OtherGoal otherGoal = OtherGoal(email, title, message);
              goalList.add(otherGoal);
            });
          }
        });
        return goalList;
      } else {
        Map&lt;String, String&gt; goals = doc.data[StringConstant.goalField] != null
            ? doc.data[StringConstant.goalField].cast&lt;String, String&gt;()
            : null;
        List&lt;Goal&gt; goalList = [];
        if (goals != null) {
          goals.forEach((title, message) {
            Goal goal = Goal(title, message);
            goalList.add(goal);
          });
        }
        return goalList;
      }
    }
  
    //Remove item from the goal list
    void removeGoal(String title, String email) {
      return _repository.removeGoal(title, email);
    }
  }
  </code></pre>