[英]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
.每当用户发送消息时,它应该更改Widget
的State
并且消息应该显示在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
我的应用程序,它会更改Widget
的State
并显示消息。 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
刷新Widget
的State
。
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:我将提供两个简单的答案:
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); }... }
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.