如何使用 StreamBuilder 更新 TextField 的值?

How to update value for TextField using StreamBuilder?

我有一个 textfield 并且我在我的应用程序中使用 sqflite 数据库。 sqflite 有一个值,我需要分配给我的 textfield

这是我的 textfield 代码

 StreamBuilder<String>(
    stream: patientHealthFormBloc.doctorName,
    builder: (context, snapshot) {
      return TextFormField(
        initialValue: patientHealthFormBloc.doctorNameValue,
        onChanged: (value) {
          patientHealthFormBloc.doctorNameChanged(value);
        },
        ...

现在,在我 class 的 initstate 方法中,我正在从数据库中获取值。 这是一个异步操作,所以需要时间。

我的集团 class 有如下代码

Function(String) get doctorNameChanged => _doctorName.sink.add;

因此,一旦我从数据库中收到值,我就会调用以下

doctorNameChanged("valuefromdatabase");

但我看不到文本字段中的值。我的数据库中也有一个值。 是否可以在不使用 TextEditingControllersetState 的情况下更新值。我想避免这些,因为我的 class 分为很多块,而且使用上述任何一种方法都太复杂了 我尝试对 RadioButtonCheckBox 使用相同的方法,它们似乎可以正确更新。 该值也在数据库中存在的 _doctorName.stream.value 中更新,但 textfield 不显示任何数据。我还尝试更改 textfield 的颜色,所以那里没有问题,而且我能够看到我输入的内容。

我做了一个应用程序的小演示 ​​https://github.com/PritishSawant/demo/tree/master/lib

我没有使用 sqflite,而是使用 shared preferences,但问题仍然存在

尝试以下方法:

StreamBuilder<String>(
  stream: patientHealthFormBloc.doctorName,
  builder: (context, snapshot) {
    String doctorName = patientHealthFormBloc.doctorNameValue;
    if(snapshot.hasData){
      doctorName = snapshot.data/*(your name string from the stream)*/;
    } 
    return TextFormField(
      initialValue: doctorName,
      onChanged: (value) {
        patientHealthFormBloc.doctorNameChanged(value);
      },
    ...

好的,所以我终于找到了解决问题的方法。

以下是我的代码,我刚刚使用 SharedPreferences 而不是 sqflite 下面的 example.Same 事情可以用 sqflite

来完成
class _MyHomePageState extends State<MyHomePage> {

  MyBloc myBloc = MyBloc();
  TextEditingController myController = TextEditingController();

  @override
  void dispose() {
    myBloc?.close();
    myController?.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    AppPreferences.setString("data", "this is my data");
    AppPreferences.getString("data").then((value){
      myBloc.dataChanged(value);
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: StreamBuilder(
          stream: myBloc.data,
           builder: (context,snapshot){

            debugPrint(snapshot.data);
            myController.value = myController.value.copyWith(text: myBloc.dataValue);

            return TextFormField(
              controller: myController,
              onChanged: (value){
                myBloc.dataChanged(value);
              },
            );
           },
        ),
      ),
    );
  }
}

我的评论中的建议是这样的:

TextEditingController _textEditingController = TextEditingController();

@override
void initState() {
  patientHealthFormBloc.doctorName.listen((snapshot){
    setState((){
      _textEditingController.text = snapshot;
    });
  });
  super.initState();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      children: <Widget>[
      TextFormField(
        controller: _textEditingController,
        onChanged: (value) {
          patientHealthFormBloc.doctorNameChanged(value);
        },
      ],
    ),
  );
}

我不想在不理解您为什么不想使用 TextEditingController 或 setState 的情况下写这个答案。但这应该在使用 Bloc 模式时实现您想要的。