我正在尝试将子窗口小部件中的文本设置为父窗口小部件.但是文本没有反映在父窗口小部件中.
试图使用setState()但仍然无法获得预期的结果.
以下是我的代码:
void main() => runApp(new TestApp());
class TestApp extends StatefulWidget {
@override
_TestState createState() => new _TestState();
}
class _TestState extends State<TestApp>{
String abc = "";
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new Column(
children: <Widget>[
new Text("This is text $abc"),
TestApp2(abc)
],
),
),
);
}
}
class TestApp2 extends StatefulWidget {
String abc;
TestApp2(this.abc);
@override
_TestState2 createState() => new _TestState2();
}
class _TestState2 extends State<TestApp2>{
@override
Widget build(BuildContext context) {
return new Container(
width: 150.0,
height: 30.0,
margin: EdgeInsets.only(top: 50.0),
child: new FlatButton(
onPressed: (){
setState(() {
widget.abc = "RANDON TEXT";
});
},
child: new Text("BUTTON"),
color: Colors.red,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
Din*_*ian 33
在您的示例中,做了一些假设.我会尽力逐一删除.
您abc从父级传递给子级,并且您在按下按钮时突变了子级值.由于原始类型在dart中按值传递,因此abc在child 中的值的更改不会更改parent的值abc.请参阅以下代码段.
void main() {
String abc = "newValue";
changeIt(abc);
print(abc); // newValue
}
void changeIt(String abc) {
abc = "newValue";
print(abc); //newValue
}
Run Code Online (Sandbox Code Playgroud)让我们假设第一个是错误的(为了理解目的).然后更改abcchild中的值将更改abc父级的值.但是,如果setState不在父母内部调用,父母将不会反映这一变化.在您的情况下,如果您更改下面的代码,它将在单击时单独更改按钮文本(因为调用child的setState).
new FlatButton(
onPressed: (){
setState(() {
widget.abc = "RANDON TEXT";
});
},
child: new Text(widget.abc), // setting the text based on abc
color: Colors.red,
)
Run Code Online (Sandbox Code Playgroud)而不是使用的globalState,这将是非常难以维持/调试为应用程序的增长,我会建议使用callbacks.请参考以下代码.
void main() => runApp(new TestApp());
class TestApp extends StatefulWidget {
@override
_TestState createState() => new _TestState();
}
class _TestState extends State<TestApp>{
String abc = "bb";
callback(newAbc) {
setState(() {
abc = newAbc;
});
}
@override
Widget build(BuildContext context) {
var column = new Column(
children: <Widget>[
new Text("This is text $abc"),
TestApp2(abc, callback)
],
);
return new MaterialApp(
home: new Scaffold(
body: new Padding(padding: EdgeInsets.all(30.0),child: column),
),
);
}
}
class TestApp2 extends StatefulWidget {
String abc;
Function(String) callback;
TestApp2(this.abc, this.callback);
@override
_TestState2 createState() => new _TestState2();
}
class _TestState2 extends State<TestApp2>{
@override
Widget build(BuildContext context) {
return new Container(
width: 150.0,
height: 30.0,
margin: EdgeInsets.only(top: 50.0),
child: new FlatButton(
onPressed: (){
widget.callback("RANDON TEXT"); //call to parent
},
child: new Text(widget.abc),
color: Colors.red,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)您缺少的一点是您的setState方法调用。您调用TestState2.
为了解决这个问题,有两种方法。
第一种方法是创建一个 GlobalKey( https://docs.flutter.io/flutter/widgets/GlobalKey-class.html ) 并将其作为参数传递给子小部件。
第二种方法是为父状态创建一个全局变量,并在子状态中使用它。
我用第二种方法修改了下面的代码。
_TestState _globalState = new _TestState();
class TestApp extends StatefulWidget {
@override
_TestState createState() => _globalState;
}
class _TestState extends State<TestApp>{
String abc = "";
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new Column(
children: <Widget>[
new Text("This is text $abc"),
TestApp2()
],
),
),
);
}
}
class TestApp2 extends StatefulWidget {
TestApp2();
@override
_TestState2 createState() => new _TestState2();
}
class _TestState2 extends State<TestApp2>{
@override
Widget build(BuildContext context) {
return new Container(
width: 150.0,
height: 30.0,
margin: EdgeInsets.only(top: 50.0),
child: new FlatButton(
onPressed: (){
_globalState.setState((){
_globalState.abc = "Button clicked";
});
},
child: new Text("BUTTON"),
color: Colors.red,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
写出非常准确的答案。只需像上面的答案一样使用回调就可以使用它。 所以你想从另一个 function/widget/class 调用 ParentScreen 的状态。只需按照此代码
import 'package:showErrorMessage.dart';
class ParentScreen extends StatefulWidget {
ParentScreen({Key key}) : super(key: key);
@override
_ParentScreenState createState() => _ParentScreenState();
}
class _ParentScreenState extends State<ParentScreen> {
callback() {
setState(() {});
}
@override
Widget build(BuildContext context) {
String message = "hello";
return Container(
child: showErrorMessage(message, callback);,
);
}
}
Run Code Online (Sandbox Code Playgroud)
这是子部件/功能/类
import 'package:flutter/material.dart';
showErrorMessage(message, Function callback) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
message,
style: TextStyle(color: Colors.white, fontSize: 16),
),
GestureDetector(
onTap: () {
callback(); // ------ this will change/rebuild the state of its parent class
},
child: Icon(
Icons.refresh,
size: 30,
color: Colors.white,
)),
],
));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11692 次 |
| 最近记录: |