首页 文章

从另一个有状态小部件调用一个有状态小部件中的方法 - Flutter

提问于
浏览
3

我有一个颤动项目,我正在努力我不能把整个代码导致它超过500行代码所以我会尝试问我的问题就像我使用imp一样简单 . 代码部分 .

我有一个有状态的小部件,并在扩展的类下面的有状态小部件中有一些函数扩展 State<MusicPlayer>

档案 lib\main.dart

只需要一个简单的功能

class MyAppState extends State<MyApp>{
...
void printSample (){
  print("Sample text");
}
...

此函数位于主类中的有状态小部件内 .

还有另一个文件 lib\MyApplication.dart

这个文件也有一个有状态的小部件,我可以做一些事情,这样我就可以在这里调用函数 printSample() ..

class MyApplicationState extends State<MyApplication>{
...
@override
  Widget build(BuildContext context) {
    return new FlatButton(
      child: new Text("Print Sample Text"),
      onPressed :(){
       // i want to cal the function here how is it possible to call the 
       // function 
       // printSample()  from here??  
      }
    );
  }
...
}

1 回答

  • 8

    要调用父项的函数,可以使用回调模式 . 在此示例中,函数( onColorSelected )将传递给子项 . 按下按钮时,孩子调用该功能:

    import 'package:flutter/material.dart';
    
    class Parent extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return ParentState();
      }
    }
    
    class ParentState extends State<Parent> {
      Color selectedColor = Colors.grey;
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            Container(
              color: selectedColor,
              height: 200.0,
            ),
            ColorPicker(
              onColorSelect: (Color color) {
                setState(() {
                  selectedColor = color;
                });
              },
            )
          ],
        );
      }
    }
    
    class ColorPicker extends StatelessWidget {
      const ColorPicker({this.onColorSelect});
    
      final ColorCallback onColorSelect;
    
      @override
      Widget build(BuildContext context) {
        return Row(
          children: <Widget>[
            RaisedButton(
              child: Text('red'),
              color: Colors.red,
              onPressed: () {
                onColorSelect(Colors.red);
              },
            ),
            RaisedButton(
              child: Text('green'),
              color: Colors.green,
              onPressed: () {
                onColorSelect(Colors.green);
              },
            ),
            RaisedButton(
              child: Text('blue'),
              color: Colors.blue,
              onPressed: () {
                onColorSelect(Colors.blue);
              },
            )
          ],
        );
      }
    }
    
    typedef ColorCallback = void Function(Color color);
    

    内部颤动小部件(如按钮或表单字段)使用完全相同的模式 . 如果您只想调用不带任何参数的函数,则可以使用 VoidCallback 类型来定义自己的回调类型 .


    如果要通知较高的父级,可以在每个层次结构级别重复此模式:

    class ColorPickerWrapper extends StatelessWidget {
      const ColorPickerWrapper({this.onColorSelect});
    
      final ColorCallback onColorSelect;
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: EdgeInsets.all(20.0),
          child: ColorPicker(onColorSelect: onColorSelect),
        )
      }
    }
    

    在Flutter中不鼓励从父窗口小部件调用子窗口小部件的方法 . 相反,Flutter鼓励您将子状态作为构造函数参数传递下去 . 您只需在父窗口小部件中调用 setState 来更新其子项,而不是调用子项的方法 .


    另一种方法是Flutter中的 controller 类( ScrollControllerAnimationController ,...) . 它们也作为构造函数参数传递给子节点,它们包含控制子节点状态的方法,而不在父节点上调用 setState . 例:

    scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);
    

    然后,孩子们需要听取这些更改以更新其内部状态 . 当然,您也可以实现自己的控制器类 . 如果您需要,我建议您查看Flutter的源代码,了解其工作原理 .


    期货和流是传递状态的另一种选择,也可以用来调用孩子的功能 .

    但我真的不推荐它 . 如果您需要调用子窗口小部件的方法,那就非常类似于您的应用程序架构存在缺陷 . Try to move the state up to the common ancestor!

相关问题