简体   繁体   English

小部件的 Flutter - State 没有变化

[英]Flutter - State of widget is not changing

I am almost new to Flutter and trying to develop a chat application.我几乎是Flutter的新手,正在尝试开发聊天应用程序。 Whenever the user sends a message it should change the State of the Widget and the message should be displayed in a Listview .每当用户发送消息时,它应该更改WidgetState并且消息应该显示在Listview中。

The case is that the Widget State does not change on Button press.情况是Widget State在按下Button时不会改变。 But if I Hot Reload my app it changes the State of the Widget and the message is displayed.但是,如果我Hot Reload我的应用程序,它会更改WidgetState并显示消息。 I am using two Widgets for the view and the setState() method is called in the Child Widget .我在视图中使用了两个Widgets ,并且在Child Widget中调用了setState()方法。 How do I refresh the State of the Widget from Child Widget .如何从Child Widget刷新WidgetState

Please review my codes and let me know the solution for it.请查看我的代码并让我知道解决方案。 Thanks in advance.提前致谢。



Parent Widget:父小部件:

class ChatScreen extends StatefulWidget {

  @override
  ChatState createState() => ChatState();
}

class ChatState extends State<ChatScreen> {

  static const int _logout = 303;

  @override
  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(
        title: Text(Strings.appNameString),
        actions: <Widget>[

          //IconButton(icon: Icon(Icons.add), onPressed: () {}),

          PopupMenuButton<int>(

            icon: Icon(Icons.more_vert),
            elevation: 10,
            //padding: EdgeInsets.all(5),
            offset: Offset(0, 100),
            itemBuilder: (BuildContext context) => [

              PopupMenuItem(child: Text("Logout"), value: _logout,),
              //PopupMenuDivider(height: 5,),
            ],
            onSelected: (value) {

              switch(value) {

                case _logout: {

                  MyClass.SignOutofGoogle();
                } break;

                default: break;
              }
            },
          ),
        ],
      ),
      body: Column(
//        crossAxisAlignment: CrossAxisAlignment.center,
//        mainAxisSize: MainAxisSize.max,
//        mainAxisAlignment: MainAxisAlignment.end,

        children: <Widget>[

          Flexible(child: ListView.builder(
              padding: new EdgeInsets.all(8.0),
              reverse: true,
              itemBuilder: (_, int index) => MyClass.messages[index],
              itemCount: MyClass.messages.length)),
          Container(
              child: ChatWidget()),
        ],
      ),
    );
  }

}



Child Widget:子部件:

class ChatWidget extends StatefulWidget {

  @override
  ChatWidgetState createState() => ChatWidgetState();
}

class ChatWidgetState extends State<ChatWidget> {

  final TextEditingController _textController = new TextEditingController();

  Widget _buildTextComposer() {
    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 10.0),

      child: Align(

        child: Column(

          children: <Widget>[
            Divider(height: 5.0, color: Colors.lightBlue,),
            Container(

              height: 6.8 * SizeConfig.heightSizeMultiplier,
              child: Row(

                children: <Widget>[
                  Container(
                    child: IconButton(
                        icon: Icon(Icons.add_photo_alternate),
                        iconSize: 6.7 * SizeConfig.imageSizeMultiplier,
                        color: Colors.lightBlueAccent,
                        onPressed: () {}),
                  ),
                  Flexible(
                    child: TextField(
                      controller: _textController,
                      onSubmitted: _handleSubmitted,
                      decoration: InputDecoration.collapsed(
                          hintText: "Send a message"),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.symmetric(horizontal: 4.0),

                    child: IconButton(
                        icon: Icon(Icons.send),
                        iconSize: 6.7 * SizeConfig.imageSizeMultiplier,
                        color: Colors.lightBlueAccent,
                        onPressed: () {
                          _handleSubmitted(_textController.text);
                        }),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _handleSubmitted(String text) {

    _textController.clear();

    ChatMessage message = new ChatMessage(
      text: text,
    );

    setState(() {
      MyClass.messages.insert(0, message);
    });
  }

  @override
  Widget build(BuildContext context) {

    return _buildTextComposer();
  }
}


class ChatMessage extends StatelessWidget {

  final String text;

  ChatMessage( {
    this.text
  });

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: const EdgeInsets.symmetric(vertical: 10.0),

      child: Row(
        //crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.end,

        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.end,

            children: <Widget>[
              //Text(MyClass.loggeduser.userName, style: Theme.of(context).textTheme.subhead),
              Text("Sajib", style: Theme.of(context).textTheme.subhead),
              Container(
                margin: const EdgeInsets.only(top: 5.0),
                child: Text(text),
              ),
            ],
          ),
          Container(
            margin: const EdgeInsets.only(right: 6.0, left: 12.0),

            child: CircleAvatar(
              //backgroundImage: NetworkImage(MyClass.loggeduser.photoUrl)),
                child: Icon(Icons.account_circle, color: Colors.lightBlueAccent,)),
          ),
        ],
      ),
    );
  }
}

Firstly, @Darish is right in that you should probably use another kind of state management system but for the question "How do I refresh the State of the Widget from Child Widget."首先,@Darish 是正确的,您可能应该使用另一种 state 管理系统,但对于“如何从子窗口小部件刷新窗口小部件的 State”这个问题。 I'll provide two simple answers:我将提供两个简单的答案:

  1. Move your _handleSubmitted method up to your ChatState widget and pass it through to your ChatWidget :将您的_handleSubmitted方法向上移动到您的ChatState小部件并将其传递给您的ChatWidget

     class ChatState extends State<ChatScreen> {... @override Widget build(BuildContext context) {... Container( child: ChatWidget(onMessageSubmitted: this._handleSubmitted)), ... } void _handleSubmitted(String text) { ChatMessage message = new ChatMessage( text: text, ); setState(() { MyClass.messages.insert(0, message); }); } }

    Then from your child widget:然后从你的孩子小部件:

     class ChatWidget extends StatefulWidget { final Function(String) onMessageSubmitted; ChatWidget({this.onMessageSubmitted}); @override ChatWidgetState createState() => ChatWidgetState(); } class ChatWidgetState extends State<ChatWidget> {... Widget _buildTextComposer() {... TextField( controller: _textController, onSubmitted: _handleSubmitted, decoration: InputDecoration.collapsed( hintText: "Send a message"), ), ... IconButton(... onPressed: () { _handleSubmitted(_textController.text); }, ), ... } void _handleSubmitted(String text) { _textController.clear(); widget.onMessageSubmitted(text); }... }
  2. Access your ChatState directly from your ChatWidgetState :直接从您的ChatWidgetState ChatState

     class ChatScreen extends StatefulWidget {... static ChatState of(BuildContext context) => context.findAncestorStateOfType<ChatState>(); } class ChatState extends State<ChatScreen> {... void onMessageSubmitted(String text) { ChatMessage message = new ChatMessage( text: text, ); setState(() { MyClass.messages.insert(0, message); }); } }

    Then in your ChatWidget you can keep as is, but in your ChatWidgetState change your _handleSubmitted method like so:然后在您的ChatWidget中您可以保持原样,但在您的ChatWidgetState中更改您的_handleSubmitted方法,如下所示:

     void _handleSubmitted(String text) { _textController.clear(); ChatScreen.of(context).onMessageSubmitted(text); }

Number 2 is closer to other arguably better methods of state management, but both are examples of updating the state of a parent widget directly from a child widget.数字 2 更接近于其他可以说更好的 state 管理方法,但两者都是直接从子 widget 更新父 widget 的 state 的示例。

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

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