首页 文章

将数据发送到Flutter中的父Widget

提问于
浏览
3

我正在尝试将子窗口小部件中的文本设置为父窗口小部件 . 但是文本没有反映在父窗口小部件中 .

试图使用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,
      ),
    );
  }
}

我错过了什么吗?

2 回答

  • 2

    在您的示例中,做了一些假设 . 我会尽力逐一删除 .

    • 您将 abc 从父级传递给子级,并且您在按下按钮时突变了子级值 . 由于原始类型在dart中是 pass by value ,因此更改child中 abc 的值将不会更改父 abc 的值 . 请参阅以下代码段 .
    void main() {
      String abc = "newValue";
      changeIt(abc);
      print(abc); // newValue
    }
    
    void changeIt(String abc) {
      abc = "newValue";
      print(abc); //newValue
    }
    
    • 让我们假设第一个是错的(为了理解目的) . 然后更改child中 abc 的值将更改父级中 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,
    )
    
    • 我建议使用 callbacks ,而不是使用 globalState ,因为app增长很难维护/调试 . 请参考以下代码 .
    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,
        ),
        );
    }
    }
    
  • 6

    您缺少的是您的 setState 方法调用 . 你调用 TestState2 的setState .

    为了解决这个问题,有两种方法 .

    第一种方法是创建一个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,
          ),
        );
      }
    }
    

相关问题