Flutter 从父类调用子类函数

22 dart flutter

代码

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
              // how can I call methodA from here?
            },
          ),
        ),
        body: HomePage(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void methodA() {}
}
Run Code Online (Sandbox Code Playgroud)

:我想打电话methodA()onPressed()IconButton。我该怎么做,我知道如何从子类调用父类的方法,但是这个用例是不同的。

ehs*_*eha 40

我认为这种情况下最好的做法是使用 Flutter 的程序员自己使用的方式!

波纹管代码是来自 Flutter代码的示例。正如您在MyCustomForm小部件中看到的那样,如果您想访问TextField小部件的文本属性(在本例中是 MyCustomForm 小部件的子部件),您需要像这样使用其控制器...

class _MyCustomFormState extends State<MyCustomForm> {
  ...
  final myController = TextEditingController();
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ...
      body: TextField(
        controller: myController,
      ),// TextField
      ...
      floatingActionButton: FloatingActionButton(
        ...
        onPressed: () {
          print(myController.text);
        },
        ...
      ),// FloatingActionButton
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

现在受此启发,并且知道 Flutter 通过引用传递其对象参数的事实,因此我们需要一个控制器类让我们的子类能够通过控制器对象访问子类的字段和函数(如上一个示例中的 TextField 小部件) ...在您的情况下,我们可以这样做:

class HomePageController {
  void Function() methodA;
}

class MyApp extends StatelessWidget {

  final HomePageController myController = HomePageController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
              myController.methodA();
            },
          ),// IconButton
        ),// AppBar
        body: HomePage(
          controller: myController,
        ),// HomePage
      ),
    );
  }
}

class HomePage extends StatefulWidget {

  final HomePageController controller;

  HomePage({ this.controller });

  @override
  _HomePageState createState() => _HomePageState(controller);
}

class _HomePageState extends State<HomePage> {

  _HomePageState(HomePageController _controller) {
    _controller.methodA = methodA;
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void methodA() {}
}
Run Code Online (Sandbox Code Playgroud)

可在该代码可以看出myController的的参考通过主页到达_HomePageState的构造函数,然后得到的引用了methodA功能...现在了methodA是在访问MyApp的通过类myController的

希望能帮助到你!:))

  • 正确的方法是使用 ```@override void initState() { super.initState(); widget.controller.methodA = methodA; }``` 并删除 _HomePageState 初始化变量,如 @Vlad 指出的那样 (10认同)
  • `不要在 createState 中放置任何逻辑。` https://dart-lang.github.io/linter/lints/no_logic_in_create_state.html (6认同)
  • 对我来说看起来是最优雅的解决方案 (5认同)

小智 31

感谢Günter Zöchbauer为我指明了正确的方向。我GlobalKey用来完成事情。但是使用GlobalKey保养

GlobalKey<_HomePageState> globalKey = GlobalKey();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
             globalKey.currentState.methodA();
            },
          ),
        ),
        body: HomePage(key: globalKey),
      ),
    );
  }
}
class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  void methodA() {}
}
Run Code Online (Sandbox Code Playgroud)


Rod*_*y R 17

2021年

typedef我相信这是使用类似构建器的小部件的最强大的解决方案。

import 'package:flutter/material.dart';

typedef MyBuilder = void Function(BuildContext context, void Function() methodA);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  late void Function() myMethod;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
              // how can I call methodA from here?
              myMethod.call();
            },
          ),
        ),
        body: HomePage(builder: (BuildContext context, void Function() methodA) {
          myMethod = methodA;
        },),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  final MyBuilder builder;

  const HomePage({Key? key, required this.builder}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    widget.builder.call(context, methodA);
    return Text('HomePage');
  }

  void methodA() {
    print('test');
  }
}

Run Code Online (Sandbox Code Playgroud)


Ben*_*sal 5

上面的答案对我不起作用,相反我只是替换了全局键并且效果很好:

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
 return MaterialApp(
  home: Scaffold(
    appBar: AppBar(
      leading: IconButton(
        icon: Icon(Icons.help),
        onPressed: () {
         //call it like this:
         HomePage.globalKey.currentState.methodA();
        },
      ),
    ),
    body: HomePage(),
  ),
);
 }
}


class HomePage extends StatefulWidget {
//Add this key like this:
static final GlobalKey<_HomePageState> globalKey = GlobalKey();
super(key: globalKey);

@override
 _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
 @override
  Widget build(BuildContext context) {
  return Container();
 }

 void methodA() {}
}
Run Code Online (Sandbox Code Playgroud)

希望一切正常:)

  • 谢谢,这确实给了我长期搜索的答案。 (2认同)