【问题标题】:How can I pass the callback to another StatefulWidget?如何将回调传递给另一个 StatefulWidget?
【发布时间】:2018-05-15 08:25:13
【问题描述】:

例如,我有两个 StatefulWidget 来监控同一个回调方法。我该怎么做?如果我有超过三个 StatefulWidget 来监控它的事件?

class WidgetOne extends StatefulWidget {
  @override
  _WidgetOneState createState() => new _WidgetOneState();
}

class _WidgetOneState extends State<WidgetOne> {

  // this is the callback, the widget two want listen the callback too
  bool _onNotification(ScrollNotification notification){

  }

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new NotificationListener(child: new ListView(shrinkWrap: true,),
          onNotification: _onNotification),
        new WidgetTwo()
      ],
    );
  }
}

class WidgetTwo extends StatefulWidget {
  @override
  _WidgetTwoState createState() => new _WidgetTwoState();
}

class _WidgetTwoState extends State<WidgetTwo> {

  // in this,How Can I get the callback in WidgetOne?
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    你不能也不应该。小部件不应依赖于其他小部件的架构。

    你有两种可能:

    • 合并WidgetTwoWidgetOne。因为将它们分开是没有意义的(至少在您提供的情况下)。
    • 修改WidgetTwo 带孩子。并将 ListView 添加为 WidgetTwo 的子代。这样它就可以将列表包装到它自己的NotificationListener 中。

    【讨论】:

      【解决方案2】:

      您的解决方案可以通过使用setState() 并在 WidgetTwo 的构造函数中传递您的状态函数来实现。我在下面做了一个例子,这个例子的主要思想是我有 MyHomePage 作为我的主要小部件和 MyFloatButton (我想自定义为另一个StatefulWidget),所以当按下 FAB 我需要在 MyHomePage 中调用增量计数器功能。让我们看看下面我是如何做到的。

      class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);
      
        final String title;
      
        @override
        _MyHomePageState createState() => new _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
        int _counter = 0;
      
        //Consider this function as your's _onNotification and important to note I am using setState() within :)
        void _incrementCounter() { 
          setState(() {
            _counter++;
          });
        }
      
        @override
        Widget build(BuildContext context) {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text(
                widget.title,
                style: TextStyle(color: Colors.white),
              ),
            ),
            body: new Center(
              child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Text(
                    'You have pushed the button $_counter times:',
                    style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
                  ),
                ],
              ),
            ),
            floatingActionButton: new MyFloatButton(_incrementCounter),//here I am calling MyFloatButton Constructor passing _incrementCounter as a function
          );
        }
      }
      
      class MyFloatButton extends StatefulWidget {
      
        final Function onPressedFunction;
      
        // Here I am receiving the function in constructor as params
        MyFloatButton(this.onPressedFunction);
      
        @override
        _MyFloatButtonState createState() => new _MyFloatButtonState();
      }
      
      class _MyFloatButtonState extends State<MyFloatButton> {
        @override
        Widget build(BuildContext context) {
          return new Container(
            padding: EdgeInsets.all(5.0),
            decoration: new BoxDecoration(color: Colors.orangeAccent, borderRadius: new BorderRadius.circular(50.0)),
            child: new IconButton(
              icon: new Icon(Icons.add),
              color: Colors.white,
              onPressed: widget.onPressedFunction,// here i set the onPressed property with widget.onPressedFunction. Remember that you should use "widget." in order to access onPressedFunction here!
            ),
          );
        }
      }
      

      现在将 MyHomePage 视为您的 WidgetOne,将 MyFloatButton 视为您的 WidgetTwo,将 _incrementCounter 函数视为您的 _onNotification。希望你能实现你想要的:)

      (我做了一般性的例子,所以任何人都可以根据他们所面临的情况来理解)

      【讨论】:

      • 你的例子显示子组件是从子组件传给父组件的,我知道,但是我的情况是父组件的回调函数传给子组件。 X
      【解决方案3】:

      您可以将内置的widget 属性用于有状态小部件。

      https://api.flutter.dev/flutter/widgets/State/widget.html

      所以在WidgetOne 会是

      new WidgetTwo(callback: callback)
      

      WidgetTwo

      class WidgetTwo extends StatefulWidget {
        final Function callback;
        
        WidgetTwo({this.callback});
      
      
        @override
        _WidgetTwoState createState() => new _WidgetTwoState();
      }
      

      _WidgetTwoState 中,您可以访问它

      widget.callback
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        • 1970-01-01
        • 1970-01-01
        • 2016-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多