【问题标题】:Pass Multiple Arguments with different data types : Flutter传递具有不同数据类型的多个参数:Flutter
【发布时间】:2020-11-19 13:43:33
【问题描述】:

我正在尝试使用 2 个不同数据类型的参数

Navigator.PushNamed(context, routeName, arguments) 

我该怎么做?

关于更多上下文,我想通过传入两个不同类型的参数从我的登陆页面导航到我的会话页面,我尝试了以下方式,但显然没有用。

Navigator.pushNamed(context, Sessions.id, arguments: SessionType.signIn, Auth())

sessionsEnum.signInsessionsEnum.signUp 设置 Sessions 类中的 SessionType 以切换登录或注册视图。而Auth() 是我的身份验证类的一个实例,用于确定用户是登录还是注销,以及 UID。在初始化时,Session 类将根据收到的参数显示视图;登录或注册。

在 Flutter 的 Navigator.pushNamed() 中传递两个非字符串参数的最佳方法是什么?

谢谢。

为清楚起见,这是我的 Sessions 课程:

class Sessions extends StatefulWidget {
  static const String id = 'sessions';
  final BaseAuth baseAuth;
  SessionType sessionType;

  Sessions({this.baseAuth, this.sessionType});

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

enum SessionType { signIn, signUp }

class _SessionsState extends State<Sessions> {
  //class wide declarations
  String email;
  String password;
  String error;

  bool showSpinner = false;
  final _formKey = GlobalKey<FormState>();

  //validate form fields input and save
  bool validateAndSave() {
    final form = _formKey.currentState;
    if (form.validate()) {
      form.save();
      print('form is valid, Email: $email, Password: $password');
      return true;
    } else {
      print('form is invalid');
      return false;
    }
  }

  String trimTextInput(String value) {
    return value.toString().trim();
  }

  void validateAndSubmit() async {
    if (validateAndSave()) {
      setState(() {
        showSpinner = true;
      });
      try {
        if (widget.sessionType == SessionType.signIn) {
          String user = await widget.baseAuth
              .handleSignIn(trimTextInput(email), trimTextInput(password));
          print('Signed in: $user');

          if (user == null) {
            setState(() {
              showSpinner = false;
              error = 'could not sign in with those credentials';
            });
          } else {
            setState(() {
              showSpinner = false;
            });
            Navigator.pushNamed(context, TakePayment.id);
          }
        } else {
          String user = await widget.baseAuth
              .handleSignUp(trimTextInput(email), trimTextInput(password));
          print('Signed up: $user');
        }
      } catch (e) {
        print('Error: ${e.toString()}');
      }
    }
  }

  void toggleViewToSignUp() {
    _formKey.currentState.reset();
    setState(() {
      widget.sessionType = SessionType.signUp;
//      _sessionType = SessionType.signUp;
    });
  }

  void toggleViewToSignIn() {
    _formKey.currentState.reset();
    setState(() {
      widget.sessionType = SessionType.signIn;
//      _sessionType = SessionType.signIn;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ModalProgressHUD(
        inAsyncCall: showSpinner,
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 24.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Flexible(
                child: Hero(
                  tag: 'logo',
                  child: Container(
                    height: 100.0,
                    child: Image.asset('images/logo.png'),
                  ),
                ),
              ),
              SizedBox(
                height: 40.0,
              ),
              Container(
                child: Form(
                  key: _formKey,
                  child: Column(
                    children: buildInputFields() + submitButtons(),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  List<Widget> buildInputFields() {
    return [
      TextFormField(
        keyboardType: TextInputType.emailAddress,
        textAlign: TextAlign.center,
        onSaved: (value) => email = value,
        validator: EmailFieldValidator.validate,
        decoration: kTextFieldDecoration.copyWith(hintText: 'enter your email'),
      ),
      SizedBox(
        height: 20.0,
      ),
      TextFormField(
        obscureText: true,
        textAlign: TextAlign.center,
        validator: PasswordFieldValidator.validate,
        onSaved: (value) => password = value,
        decoration:
            kTextFieldDecoration.copyWith(hintText: 'enter your password'),
      ),
      SizedBox(
        height: 20.0,
      ),
    ];
  }

  List<Widget> submitButtons() {
    if (widget.sessionType == SessionType.signIn) {
//    if (_sessionType == SessionType.signIn) {
      return [
        Buttons(
          buttonLabel: 'Sign In',
          buttonColour: kThemeStyleButtonFillColour,
          buttonTextStyle: kThemeStyleButton,
          onPressedButton: validateAndSubmit,
        ),
        SizedBox(
          height: 20.0,
        ),
        PaddedClickableText(
          myText: 'Don\'t have an account? Sign up now',
          onTap: toggleViewToSignUp,
        ),
      ];
    } else {
      return [
        Buttons(
          buttonLabel: 'Sign Up',
          buttonColour: kThemeStyleButtonFillColour,
          buttonTextStyle: kThemeStyleButton,
          onPressedButton: validateAndSubmit,
        ),
        SizedBox(
          height: 20.0,
        ),
        PaddedClickableText(
          myText: 'Already have an account? Sign in here',
          onTap: toggleViewToSignIn,
        ),
      ];
    }
  }
}

class EmailFieldValidator {
  static String validate(String value) {
    return value.isEmpty ? 'Email can\'t be empty' : null;
  }
}

class PasswordFieldValidator {
  static String validate(String value) {
    return value.length < 6 || value.isEmpty
        ? 'Password can\'t be empty'
        : null;
  }
}

这是我的 Onboarding5 中使用 Navigator.pushNamed() 的代码...

class Onboarding5 extends StatelessWidget {
  static const String id = 'onboarding5';
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Flexible(
              child: Hero(
                tag: 'logo',
                child: Padding(
                  padding:
                      const EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0),
                  child: Image.asset('images/logo_text.png'),
                ),
              ),
            ),
            PaddingClass(
              bodyImage: 'images/start_here.png',
            ),
            Text(
              'Start here',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: kHeading1TextSize,
                color: kThemeTextColour,
                fontWeight: FontWeight.w700,
              ),
            ),
            Buttons(
              onPressedButton: () {
//                Navigator.pushNamed(context, Sessions.id);
                Navigator.pushNamed(context, Sessions.id,
                    arguments: [SessionType.signUp, Auth()]);
              },
              buttonLabel: 'Sign Up',
              buttonColour: kWhiteButtonFillColour,
              buttonTextStyle: kWhiteButtonStyle,
            ),
            Buttons(
              onPressedButton: () {
//                Navigator.pushNamed(context, RootPage.id, arguments: Auth());
//                Navigator.pushNamed(context, Sessions.id);
                Navigator.pushNamed(context, Sessions.id,
                    arguments: [SessionType.signIn, Auth()]);
              },
              buttonLabel: 'Sign in',
              buttonColour: Colors.white,
              buttonTextStyle: kWhiteButtonStyle,
            ),
            SizedBox(
              height: 10.0,
            ),
            Align(
              alignment: Alignment.center,
              child: Text(
                'We\'re social. Connect with us.',
                style: kRegularTextStyle,
              ),
            ),
            Padding(
              padding: EdgeInsets.fromLTRB(80.0, 10.0, 80.0, 10.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  //TODO: Add an ontap listener to navigate to their respective social media pages when user clicks
                  Icon(
                    FontAwesomeIcons.facebookSquare,
                    color: kThemeIconColour,
                  ),
                  Icon(
                    FontAwesomeIcons.twitterSquare,
                    color: kThemeIconColour,
                  ),
                  Icon(
                    FontAwesomeIcons.instagramSquare,
                    color: kThemeIconColour,
                  ),
                  Icon(
                    FontAwesomeIcons.linkedinIn,
                    color: kThemeIconColour,
                  ),
                  Icon(
                    Icons.mail,
                    color: kThemeIconColour,
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: firebase flutter firebase-authentication


    【解决方案1】:

    参数是Object,因此您可以将任何对象传递给它。在您的情况下,您可以将两个参数作为列表传递,也可以通过 Map&lt;String, dynamic&gt; 的映射传递它们,或者您甚至可以创建另一个包含这两个对象的类。选择权在你。

    将它们作为地图传递。

    Navigator.pushNamed(context, Sessions.id, arguments: {'session' : SessionsArgument(sessionEnum.signIn), 'auth' : Auth()}); 
    

    将它们作为列表传递

    Navigator.pushNamed(context, Sessions.id, arguments: [SessionsArgument(sessionEnum.signIn),Auth()]); 
    

    通过创建数据类来传递它们。

    Class ArgumentsClass {
      final SessionsArgument sessionArgument;
      final Auth auth;
      ArgumentsClass(this.sessionArgument,this.auth);
    }
    
    Navigator.pushNamed(context, Sessions.id, arguments: ArgumentsClass(SessionsArgument(sessionEnum.signIn),Auth()));
    

    要检索参数,请使用 ModalRoute 设置。

    List<dynamic> args = ModalRoute.of(context).settings.arguments;
    

    【讨论】:

    • 这不太行。我使用 Navigator.pushNamed(context, Sessions.id, arguments: [SessionType.signIn, Auth()]);和 Navigator.pushNamed(context, Sessions.id, arguments: [SessionType.signUp, Auth()]);但它不会切换。只有注册一个有效。好吧。
    • 当我在我的 Sessions Stateful 类中将我的 SessionType 声明为 final 时,由于此错误,它不允许我使用 widget.sessionType 访问 SessionType:lib/sign_in_up_screens/sessions.dart:93:14 : 错误:没有为“Sessions”类定义设置器“sessionType”。
    • 我试过这个。导航到 SessionClass 后,它不会切换正确的视图。我在上面编辑了我的问题以显示我的整个 SessionsClass
    • @hermie_brown 添加您在哪里调用 navigator.pushNamed 的代码。
    • 完成。编辑了我上面的问题以反映我的 Onboarding5.dart
    【解决方案2】:

    试试

    Navigator.pushNamed(context, Sessions.id, arguments: [SessionsArgument(sessionEnum.signIn), Auth()])
    

    【讨论】:

    • 我试过这个。导航到 SessionClass 后,它不会切换正确的视图。我在上面编辑了我的问题以显示我的整个 SessionsClass
    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 2023-03-08
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2015-12-29
    • 1970-01-01
    相关资源
    最近更新 更多