Flutterの入力ダイアログでは、ControllerをダイアログのStateに持たせる

結論

Flutterで TextEditingController を使う入力ダイアログを作るなら、Controllerはダイアログの State で生成し、State.dispose で破棄します。showDialog の完了後も終了アニメーション中は入力欄が残るため、呼び出し側ですぐ破棄すると、表示中の入力欄から参照されるおそれがあります。

僕が実装した入力ダイアログでは、呼び出し側が showDialog の完了を待ってControllerを破棄すると、終了アニメーション中に「破棄後に使われた」というエラーが出ました。Navigator.pop で返り値が確定する時点と、画面からダイアログが取り除かれる時点は同じではありません。

そこでControllerをダイアログの State で作り、ダイアログが画面から取り除かれるときに呼ばれる State.dispose で破棄するようにしました。これなら、入力欄が残っている間はControllerも残ります。

Controllerの寿命は、それを作った関数ではなく、最後まで参照するWidgetに合わせるのが判断の基準です。