如何使用StreamBuilder更新TextField的值?


13

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

这是我的textfield代码

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

现在,在initstate我课堂上的方法中,我正在从数据库中获取价值。这是异步操作,因此需要时间。

我的bloc类具有如下代码

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

因此,一旦我从数据库中获得价值,我就会立即致电

doctorNameChanged("valuefromdatabase");

但我看不到文本字段中的值。我的数据库中也有一个值。是否可以不使用TextEditingController或来更新值setState。我是个试图避免那些因为我的课是很多chuncks和方式过于复杂,使用任何上述我一直在使用与同样的方法试了划分RadioButton,并CheckBox和他们似乎正确更新。_doctorName.stream.value数据库中存在的值也会更新, 但textfield不会显示任何数据。我也试图改变颜色,textfield所以那里没有问题,以及我能够看到我输入的内容。

我已经对该应用程序做了一个小演示https://github.com/PritishSawant/demo/tree/master/lib

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


尝试删除“初值:patientHealthFormBloc.doctorNameValue”,并启动它从StreamBuilder的“initialData”
STEL

@Stel谢谢,但不起作用

您可以使用TextEditingController(text:)

@ChinkySight我正在使用Stream来避免TextEditingController。该应用程序很复杂,使用TextEditingController是不可行的

在您的示例中,您根本没有使用快照。您希望从中提取什么数据以在TextFormField中使用?为什么不能使用TextEditingController?
若昂·苏亚雷斯

Answers:


4

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

以下是我的代码,我只是用SharedPreferences代替sqflite下面的示例。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);
              },
            );
           },
        ),
      ),
    );
  }
}

这是一个过度设计的解决方案。我希望您已经解释了您最初想要实现的目标,而不是希望我们解决您的特定解决方案。当我对您的问题发表评论时,您似乎想要实时更新可能正在被用户积极使用的TextField。这是非常奇怪的,可能是不良的UX。
若昂·苏亚雷斯

@JoãoSoares可以发布您的解决方案。如果能提供比我更好的奖励,我将非常乐意奖励。我刚刚发布了一个更简单的解决方案,因此每个人都可以理解,但实际上我的应用程序需要与sqflite和Firestore进行同步,因此它可能看起来像是为您设计的
Nudge

如果您可以解释为什么要在用户使用它的同时流式处理(更新)TextFieldForm的值,我可能会为您提供帮助。与SQFlite和Firestore同步并没有涉及我声称您提出的解决方案经过精心设计的说法。
若昂·苏亚雷斯

@JoãoSoares请再次阅读问题。
轻推

我已经多次阅读了该问题,并看到了您在GitHub上共享的代码。您的解释说明了您想做什么以及如何编写代码。它没有解释为什么您要用数据流或以这种行为为前提以文本方式填充TextFormField的原因。
若昂·苏亚雷斯

2

请尝试以下方法:

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);
      },
    ...

让我知道您是否需要更多帮助。


不工作...
微调

您在流媒体中收到新名字吗?
Harshvardhan Joshi

是的,但是值没有更新

您在收到相同的新名字builder: (context, snapshot)吗?
Harshvardhan Joshi

当我键入文本时,我收到键入的文本。在当我从数据库中获取则打印分贝价值。StreamBuilder工作正常和值更新时,我手动键入但是当它被取出从数据库中它不更新的初始阶段
微调

1

我的评论中暗示的是这样的:

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模式时实现所需的功能。


我一开始就有这种想法,但是由于引用了这个问题,并且@Nudge坚持不使用TextEditController,所以我取消了这个想法。伟大的是,仅通过使用控制器,解决方案就变得简单而又难以精确地工作。做得好。
Harshvardhan Joshi

1
谢谢你,我很感激。不幸的是,用户似乎坚持要坚持自己的想法,而不是尝试编写适当的解决方案,因为他们决定不归因于正确的回应或悬赏。
若昂·苏亚雷斯

哦好的。没关系。
Harshvardhan Joshi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.