flutter - Flutter-小部件的状态未更改

标签 flutter dart widget state

我几乎是Flutter的新手,正在尝试开发聊天应用程序。每当用户发送消息时,都应更改StateWidget,并且消息应显示在Listview中。
这种情况是在按Widget StateButton不变。但是,如果我对应用程序进行Hot Reload更改,则会更改StateWidget并显示消息。我在 View 中使用两个Widgets,并且在setState()中调用了Child Widget方法。如何从State刷新WidgetChild 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()),
        ],
      ),
    );
  }

}

子小部件:
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,)),
          ),
        ],
      ),
    );
  }
}

最佳答案

首先,@ Darish是正确的,因为您可能应该使用另一种状态管理系统,但要问“如何从子窗口小部件刷新窗口小部件的状态”这一问题。我将提供两个简单的答案:

  • _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);
        });
      }
    }
    

    然后从您的 child 小部件:
    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);
      }
      ...
    }
    
  • 直接从ChatState访问您的ChatWidgetState:
    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);
        });
      }
    }
    

    然后可以在ChatWidget中保持原样,但是在ChatWidgetState中,像下面这样更改_handleSubmitted方法:
    void _handleSubmitted(String text) {
      _textController.clear();
    
      ChatScreen.of(context).onMessageSubmitted(text);
    }
    

  • 数字2更接近于其他可以说是更好的状态管理方法,但是两者都是直接从子窗口小部件更新父窗口小部件的状态的示例。

    关于flutter - Flutter-小部件的状态未更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60187297/

    相关文章:

    flutter - 如何在 flutter 中达到这种形状?

    android - 无法构建 Flutter Android Build : Received status code 502 from server: Bad Gateway

    animation - 如何链接多个 Controller /动画?

    dart - Dart:以String作为参数的函数作为回调中的参数

    flutter - 有没有办法在全屏模式下以抖动的方式播放视频?

    android AppWidget 按钮解绑

    class - 将List <object>添加到类

    flutter - 无法从抽屉中关闭alertDialog

    jquery - 如何改进用 CoffeeScript 编写的 Jquery Widget?

    widget - Flutter Row 在构建时消失了吗?