【问题标题】:Flutter - Issue with callback functionFlutter - 回调函数的问题
【发布时间】:2019-01-29 07:36:44
【问题描述】:

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

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

问题概述:

RootPage > TabNavigator > SearchPage > ProfilePageProfilePage 上有注销按钮)。不工作。

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;
  }

代码sn-p:

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 返回currentPage = SearchPage)。

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

我不知道如何让onPressed 回调函数将其输出传回RootPage

如果不粘贴完整的代码很难解释,但我希望你明白这个概念。

【问题讨论】:

  • 您是否在控制台中遇到任何错误?
  • 不,控制台中没有错误

标签: dart flutter


【解决方案1】:

您可以在根级别(即 _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
)

【讨论】:

    【解决方案2】:

    因为它在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()

    【讨论】:

    • 感谢您的回复。这并不能解决我的问题。我用额外的细节和代码 sn-ps 重写了这个问题。
    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2022-12-07
    • 2020-08-02
    • 2011-01-27
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多