Flutter-回调函数出现问题

时间:2018-08-23 01:08:34

标签: dart flutter

我到处搜索,找不到简单的解决方案。我是编码新手,还是Flutter / Dart的新手。

我怀疑这是一个非常基本的问题。我需要通过中间部件将回调传递给最终部件。

问题概述:

RootPage> TabNavigator> SearchPage> ProfilePage(在ProfilePage上具有注销按钮)。不起作用。

RootPage中,有问题的代码是:

  @override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.notDetermined:
        return _buildWaitingScreen();
      case AuthStatus.notSignedIn:
        return LoginPage(
          onSignedIn: _signedIn,
        );
      case AuthStatus.signedIn:
        return TabNavigation(
          ProfilePage(onSignedOut: _signedOut,)
        );
    }
    return null;
  }

RootPage> SearchPage(此SearchPage上的注销按钮)。可以使用以下代码:

@override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.notDetermined:
        return _buildWaitingScreen();
      case AuthStatus.notSignedIn:
        return LoginPage(
          onSignedIn: _signedIn,
        );
      case AuthStatus.signedIn:
        return SearchPage(
          onSignedOut: _signedOut,
        );
    }
    return null;
  }

代码段:

class ProfilePage extends StatelessWidget {
  ProfilePage({this.onSignedOut});
  final VoidCallback onSignedOut;

 @override
    Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Manage Profile'),
            actions: <Widget> [
              new FlatButton(
                child: new Text('Logout', style: new TextStyle(fontSize: 17.0, color: Colors.white)),
                onPressed: () => _signOut(context)
.....
....


class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.notDetermined;

@override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.notDetermined:
        return _buildWaitingScreen();
      case AuthStatus.notSignedIn:
        return LoginPage(
          onSignedIn: _signedIn,
        );
      case AuthStatus.signedIn:
        return TabNavigation(
          ProfilePage(onSignedOut: _signedOut), 
        );
    }
    return null;
  }
我的应用程序的

主页是RootPage,用于管理用户的登录状态。登录后,RootPage返回TabNavigation,这是管理bottomNavigationbar的实用程序,默认情况下返回SearchPage(即setState返回{{1 }} = currentPage

我现在希望在SearchPage上具有注销按钮。

我不知道如何获取ProfilePage回调函数以将其输出传递回onPressed

在不粘贴完整代码的情况下很难解释,但是希望您能理解。

2 个答案:

答案 0 :(得分:0)

由于它在SearchPage中工作,因此应该很简单。请参考以下代码,

class SearchPage extends StatefulWidget {
  final VoidCallback onSignedOut;

  SearchPage(this.onSignedOut); //getting from RootPage (might be via TabNavigator)

  @override
  State<StatefulWidget> createState() {
    return new _SearchPage();
  }

}

class _SearchPage extends State<SearchPage> {
  @override
  Widget build(BuildContext context) {
    var route = MaterialPageRoute(
        builder: (context) => ProfilePage(this.widget.onSignedOut)); // sending the callback to ProfilePage
    Navigator.push(context, route);
  }
}

class ProfilePage extends StatelessWidget {
  ProfilePage(this.onSignedOut);
  final VoidCallback onSignedOut;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
        title: new Text('Manage Profile'),
    actions: <Widget> [
    new FlatButton(
    child: new Text('Logout', style: new TextStyle(fontSize: 17.0, color: Colors.white)),
    onPressed: () => onSignedOut() //invoking the callback which will execute in RootPage
    //....
  }
}

注意:在您的ProfilePage中,onPressed方法名称看起来错误_signOut(context)。如果您使用某种私有方法来调用onSignedOut,那很好。否则,您必须使用onSignedOut()

答案 1 :(得分:0)

您可以在根级别(即_RootPageState类)使用InheritedWidget。现在,您可以在层次结构的任何位置向下传递任何信息(数据)。就您而言,onPressed会在ProfilePage中使用。

class LogoutAction extends InheritedWidget {
  const LogoutAction({
    Key key,
    @required this.logoutButtonClick,
    @required Widget child,
  }) : assert(logoutButtonClick != null),
       assert(child != null),
       super(key: key, child: child);

  final VoidCallback logoutButtonClick;

  static LogoutAction of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(LogoutAction);
  }

  @override
  bool updateShouldNotify(LogoutAction old) => logoutButtonClick != old.logoutButtonClick;
}

现在可以在以下位置使用此LogoutAction小部件

class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.notDetermined;

  _logoutClick() {
    //your code
  }

  @override
  Widget build(BuildContext context) {
    return LogoutAction(
      logoutButtonClick: _logoutClick,
      child: //todo: child widget that will use ProfilePage
    );
  }
}

,您的注销按钮将如下所示:

FlatButton(
  onPressed: LogoutAction.of(context).logoutButtonClick
)