从父类颤振调用子类函数

时间:2018-12-09 13:29:08

标签: 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() {}
}

问题: 我想从methodA()的{​​{1}}呼叫onPressed()。我该怎么做,我知道如何从子类中调用父方法,但是这种用例是不同的。

4 个答案:

答案 0 :(得分:28)

我认为在这种情况下,最佳实践是使用Flutter的程序员使用自己的方式!

下面的代码是Flutter source中的一个示例。如您要在 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
    );
  }
}

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

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() {}
}

在此代码中可以看到 myController 的引用通过 Home 到达 _HomePageState 的构造函数,然后获取引用的 methodA 功能...,现在可以通过 myController MyApp 类中访问 methodA

希望有帮助! :))

答案 1 :(得分:1)

感谢Günter Zöchbauer为我指出正确的方向。我正在使用 app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = clientId, //Authority = authority, MetadataAddress = metadataAddress, RedirectUri = postLogoutRedirectUri, PostLogoutRedirectUri = postLogoutRedirectUri, Notifications = new OpenIdConnectAuthenticationNotifications { AuthenticationFailed = context => { context.HandleResponse(); context.Response.Redirect("/Error?message=" + context.Exception.Message); return Task.FromResult(0); }, AuthorizationCodeReceived = context => { string authorizationCode = context.Code; // (tricky) the authorizationCode is available here to use, but... return Task.FromResult(0); } }); 完成任务。但是,将GlobalKeycare

一起使用
GlobalKey

答案 2 :(得分:0)

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

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() {}
}

希望一切正常:)

答案 3 :(得分:-1)

实际上,您不能这样做,因为_HomePageState是私有的。删除HomePageState前面的_符号,这样它将是公共的,您可以使用HomePageState().methodA();

调用methodA()