Flutterの初期値があるTextFieldでバリデーション

BLoCパターンでログイン用メールアドレスなどの初期表示地があるフォームでのバリデーションを実装しました。

重要なコード

TextFieldのcontrollerの値にsnapshot.dataをセットする必要があります。実装は下記のコードを参考にしてください。

TextEditingController _emailTextController = TextEditingController();


_emailTextController.value = _emailTextController.value.copyWith(
  text: snapshot.data,    
);

UI側

return StreamBuilder<String>(
 stream: _bloc.email,
 builder: (_, AsyncSnapshot<String> snapshot) {
   _emailTextController.value = _emailTextController.value.copyWith(
     text: snapshot.data,    
   );
   return TextField(
     controller: _emailTextController,
     onChanged: _bloc.changeEmail,
     decoration: InputDecoration(
       border: InputBorder.none,
       hintText: FieldLabelConstant.email,
       errorText: snapshot.error,
     ),
   );
 },
);

BLoC側

final BehaviorSubject<String> _email = BehaviorSubject<String>();
Observable<String> get email => _email.stream.transform(_validateName);
Function(String) get changeEmail => _email.sink.add;

バリデーション処理

final StreamTransformer<String, String> _validateEmail =
    StreamTransformer<String, String>.fromHandlers(
        handleData: (String email, EventSink<String> sink) {
  if (email.contains('@')) {
    sink.add(email);
  } else {
    sink.addError('');
  }
});

全てはポテトのために