简体   繁体   English

关于 Flutter State 和从 State 与 StatefulWidget 检索变量的问题

[英]Question about Flutter State and retrieving variables from State vs StatefulWidget

Here's the context :这是上下文

In my app, users can create a question, and all questions will be displayed on a certain page.在我的应用程序中,用户可以创建一个问题,所有问题都会显示在某个页面上。 This is done with a ListView.builder whose itemBuilder property returns a QuestionTile.这是通过 ListView.builder 完成的,它的 itemBuilder 属性返回 QuestionTile。

The problem :问题

If I create a new question, the text of the new question is (usually) displayed as the text of the previous question.如果我创建一个新问题,问题的文本(通常)显示为前一个问题的文本。

Here's a picture of me adding three questions in order, "testqn123", "testqn456", "testqn789" , but all are displayed as "testqn123" .这是我按顺序添加三个问题的图片, "testqn123", "testqn456", "testqn789" ,但都显示为"testqn123"

在此处输入图像描述

Hot restarting the app will display the correct texts for each question, but hot reloading wont work.热重启应用程序将显示每个问题的正确文本,但热重新加载将不起作用。

In my _QuestionTileState class, if I change the line responsible for displaying the text of the question on the page, from在我的 _QuestionTileState class 中,如果我更改负责在页面上显示问题文本的行,从

child: Text(text)

to

child: Text(widget.text)

the issue will be resolved for good.这个问题将得到解决。 I'm not super familiar with how hot restart/reload and state works in flutter, but can someone explain all of this?我不太熟悉热重启/重新加载和 state 在 flutter 中的工作原理,但是有人可以解释这一切吗?

Here is the code for QuestionTile and its corresponding State class, and the line changed is the very last line with words in it :这是 QuestionTile 及其对应的 State class 的代码,更改的行是其中包含单词的最后一行

class QuestionTile extends StatefulWidget {
  final String text;
  final String roomName; 
  final String roomID; 
  final String questionID; //

  QuestionTile({this.questionID, this.text, this.roomName, this.roomID});

  @override
  _QuestionTileState createState() => _QuestionTileState(text);
}

class _QuestionTileState extends State<QuestionTile> {
  final String text;
  int netVotes = 0;
  bool expand = false;
  bool alreadyUpvoted = false;
  bool alreadyDownvoted = false;

  _QuestionTileState(this.text);

  void toggleExpansion() {
    setState(() => expand = !expand);
  }

  @override
  Widget build(BuildContext context) {
    RoomDbService dbService = RoomDbService(widget.roomName, widget.roomID);
    final user = Provider.of<User>(context);

    print(widget.text + " with questionID of " + widget.questionID);

    return expand
        ? ExpandedQuestionTile(text, netVotes, toggleExpansion)
        : Card(
            elevation: 10,
            child: Padding(
              padding: const EdgeInsets.fromLTRB(10, 7, 15, 7),
              child: GestureDetector(
                onTap: () => {
                  Navigator.pushNamed(context, "/ChatRoomPage", arguments: {
                    "question": widget.text,
                    "questionID": widget.questionID,
                    "roomName": widget.roomName,
                    "roomID": widget.roomID,
                  })
                },
                child: new Row(
                  // crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    Column(
                      // the stack overflow functionality
                      children: <Widget>[
                        InkWell(
                          child: alreadyUpvoted
                              ? Icon(Icons.arrow_drop_up,
                                  color: Colors.blue[500])
                              : Icon(Icons.arrow_drop_up),
                          onTap: () {
                            dynamic result = dbService.upvoteQuestion(
                                user.uid, widget.questionID);
                            setState(() {
                              alreadyUpvoted = !alreadyUpvoted;
                              if (alreadyDownvoted) {
                                alreadyDownvoted = false;
                              }
                            });
                          },
                        ),
                        StreamBuilder<DocumentSnapshot>(
                          stream: dbService.getQuestionVotes(widget.questionID),
                          builder: (context, snapshot) {
                            if (!snapshot.hasData) {
                              return Center(child: CircularProgressIndicator());
                            } else {
                              // print("Current Votes: " + "${snapshot.data.data["votes"]}");
                              // print("questionID: " + widget.questionID);
                              return Text("${snapshot.data.data["votes"]}");
                            }
                          },
                        ),
                        InkWell(
                          child: alreadyDownvoted
                              ? Icon(Icons.arrow_drop_down,
                                  color: Colors.red[500])
                              : Icon(Icons.arrow_drop_down),
                          onTap: () {
                            dbService.downvoteQuestion(
                                user.uid, widget.questionID);
                            setState(() {
                              alreadyDownvoted = !alreadyDownvoted;
                              if (alreadyUpvoted) {
                                alreadyUpvoted = false;
                              }
                            });
                          },
                        ),
                      ],
                    ),

                    Container(
                      //color: Colors.red[100],
                      width: 290,
                      child: Align(
                          alignment: Alignment.centerLeft,
                          child: Text(text)), // problem solved if changed to Text(widget.text)
                    ),

                   

                    

  }
}

You can wrap your UI with a Stream Builder, this will allow the UI to update every time any value changes from Firestore.您可以使用 Stream 构建器包装您的 UI,这将允许 UI 在每次从 Firestore 更改任何值时更新。

Since you are using an item builder you can wrap the widget that is placed with the item builder.由于您使用的是项目构建器,因此您可以包装与项目构建器一起放置的小部件。

That Should update the UI那应该更新用户界面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM