代码之家  ›  专栏  ›  技术社区  ›  Aman Malhotra

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

  •  20
  • Aman Malhotra  · 技术社区  · 6 年前

    我正在做一个flutter项目,我不能把整个代码放进去,因为它有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??  
          }
        );
      }
    ...
    }
    
    3 回复  |  直到 5 年前
        1
  •  30
  •   boformer    6 年前

    要调用父函数,可以使用回调模式。在这个例子中,一个函数( 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 在父窗口小部件中更新其子窗口。


    另一种方法是 controller 颤振课程( ScrollController ,请 AnimationController ,…)。这些也作为构造函数参数传递给子级,它们包含控制子级状态的方法,而不调用 设置状态 在父母身上。例子:

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

    然后,要求子级侦听这些更改以更新其内部状态。当然,您也可以实现自己的控制器类。如果需要的话,我建议您查看flutter的源代码,了解它是如何工作的。


    期货和流是传递状态的另一种选择,也可以用来调用子函数。

    但我真的不推荐。如果您需要调用子小部件的方法,就好像您的应用程序体系结构有缺陷一样。 试着把国家提升到共同的祖先!

        2
  •  2
  •   mnabeelx    5 年前

    我通过反复试验找到了另一个解决方案,但它奏效了。

    import 'main.dart' as main;
    

    然后在onpressed下添加此行。

    main.MyAppState().printSample();
    
        3
  •  2
  •   mkf    5 年前

    如果要调用printsample()func,可以使用:

    class Myapp extends StatefulWidget{
    ...
        MyappState myAppState=new MyappState();
        @override
        MyappState createState() => myAppState;
        void printSample(){
            myAppState.printSample();
        }
    }
    class MyAppState extends State<MyApp>{
        void printSample (){
            print("Sample text");
        }
    }
    
    ...............
    Myapp _myapp = new Myapp();
    myapp.printSample();
    ...