flutter StreamBuilderから遷移した画面のStreamBuilder内のTextFieldを初期化する

困った。StreamBuilderで作ったList画面から、これまたStremBuilderで作ったEdit画面へ画面遷移。

Edit画面のStreamBuilder内にTextFieldを置いて、Streamから取得した値で初期化しようとすると、キーボードを表示する度にStreamが流れてしまい、編集しようとも初期化しようとする値に戻ってしまう。

EditScreenのStremが流れるたびに呼び出し元のListScreenにもStreamが流れてしまい、想定した動きにならない。

仕方ないのでEditScreenに初期化済み判定用のフラグを用意してみた。

class ListScreen extends StatelessWidget {

  // APIからデータを取得してストリームに流し込むことを想定
  Stream<List<String>> _stream = Stream<List<String>>.value(
      ["Title1", "Title2", "Title3", "Title4", "Title5"]);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: const Text("First Screen")),
        body: StreamBuilder(
          stream: _stream,
          builder: (context, AsyncSnapshot<List<String>> snapshot) {
            if (!snapshot.hasData) {
              return Container();
            }

            return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  return InkWell(
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => DetailScreen(),
                      ));
                    },
                    child: Card(
                      child: Container(
                          margin: EdgeInsets.all(10.0),
                          child: Text(snapshot.data[index])),
                    ),
                  );
                });
          },
        ));
  }
}

class DetailScreen extends StatefulWidget {
  DetailScreen();

  @override
  State<StatefulWidget> createState() => DetailScreenState();
}

class DetailScreenState extends State<DetailScreen> {
  // APIから取得してデータをストリームに流し込むことを想定
  Stream<String> _stream = Stream<String>.value("this is id='s data");

  // TextFieldを初期化済みかどうかを管理するためのフラグ
  bool _initialize = false;

  final _titleTextController = TextEditingController();

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Second Screen")),
      body: StreamBuilder(
          stream: _stream,
          builder: (context, AsyncSnapshot<String> snapshot) {
            if (!snapshot.hasData) {
              return Container();
            } else if (!_initialize) {
              // ストリームから流れてきたデータをTextFieldの初期値にセット
              // ただしSoftwareKeyboardの表示・非表示が切り替わるたびにStreamが
              // 流れてくるため、初期化済みか判定用のフラグ管理する
              _titleTextController.text = snapshot.data;
              _initialize = true;
            }
            return Container(
              child: Column(
                children: <Widget>[
                  TextFormField(
                    controller: _titleTextController,
                    decoration: InputDecoration(labelText: "Title"),
                  ),
                ],
              ),
            );
          }),
    );
  }
}

これはもうちょっと使い方調べないとダメやな。
provider packageのStreamProvider使って同じことしてみる。