【问题标题】:How to initialise a type ValueChanged in Dart/Flutter?如何在 Dart/Flutter 中初始化类型 ValueChanged?
【发布时间】:2021-10-05 22:59:55
【问题描述】:

我是 Flutter 的新手,特别是 Flutter for Web。我正在尝试做一些简单而基本的事情,但我遇到了困难。

这是我的 main.dart

Widget build(BuildContext context) {
bool loggedIn = false;
return MaterialApp(
  home: loggedIn ? Navigator(
    pages: [
      MaterialPage(child: DashboardPage())
    ],
    onPopPage: (route, result) => route.didPop(result),
  ) : LoginPage(didLoggedIn: (user) => print('Hello, ' + user) )
);
}
}

我要存档的内容:如果未登录,请转到登录屏幕。用户成功登录后,我想执行一个打印hello的回调(实际上我会将状态设置为已登录,但没关系)。

但是我在实现这个回调时遇到了困难,也许我做错了。这是登录页面代码:

import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';

class LoginPage extends StatefulWidget {
  @override
  LoginPageState createState() {
    return LoginPageState();
  }
}
class LoginPageState extends State<LoginPage> {
  final username = TextEditingController();
  final password = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  bool rememberMe = true;
  //final ValueChanged didLoggedIn;
  Widget _buildUsernameField() {
    return TextFormField(
        controller: username,
        decoration: InputDecoration(labelText: 'Your E-Mail'),
        validator: (value) {
          if (value == null ||
              value.isEmpty ||
              !EmailValidator.validate(value)) {
            return 'Invalid E-Mail';
          }
          return null;
        });
  }

  Widget _buildPasswordField() {
    return TextFormField(
        controller: password,
        obscureText: true,
        decoration: InputDecoration(labelText: 'Password'),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return 'Please enter your password';
          }
          return null;
        });
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Container(
        color: Colors.white,
        alignment: Alignment.center,
        child: Container(
          //color: Colors.green,
          width: 600,
          height: 300,
          child: Column(
            children: [
              Form(
                key: _formKey,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    _buildUsernameField(),
                    _buildPasswordField(),
                  ],
                ),
              ),
              Column(
                children: [
                  CheckboxListTile(title: Text('Remember me') ,
                      controlAffinity: ListTileControlAffinity.leading,
                      value: rememberMe, onChanged: (bool? value) {
                        setState(() {
                          rememberMe = value!;
                        });
                      }),
                  ElevatedButton(
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        print(username.text + "/" + password.text);
                        //didLoggedIn(username.text);
                      }
                    },
                    child: Text('Log me in'),
                  ),
                  Text('Forgot your password ?')
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

问题是这一行:final ValueChanged didLoggedIn;

它说我需要初始化它。该怎么做?

顺便说一句,正如我所说,我是新手,所以也许这不是归档我的目标的最佳方式,所以如果有人想给我一个更好的解决方案,这将非常受欢迎。

谢谢!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您需要更改“登录页面”,如下所示。

    • 将“didLoggedIn”移动到“LoginPage”而不是“LoginPageState”。
    • 制作“LoginPage”的构造函数来接收“didLoggedIn”
    • 使用“小部件”访问“didLoggedIn”。前缀。
    import 'package:flutter/material.dart';
    import 'package:email_validator/email_validator.dart';
    
    class LoginPage extends StatefulWidget {
      final ValueChanged didLoggedIn;
    
      LoginPage({required this.didLoggedIn});
    
      @override
      LoginPageState createState() {
        return LoginPageState();
      }
    }
    class LoginPageState extends State<LoginPage> {
      final username = TextEditingController();
      final password = TextEditingController();
      final _formKey = GlobalKey<FormState>();
      bool rememberMe = true;
    
      Widget _buildUsernameField() {
        return TextFormField(
            controller: username,
            decoration: InputDecoration(labelText: 'Your E-Mail'),
            validator: (value) {
              if (value == null ||
                  value.isEmpty ||
                  !EmailValidator.validate(value)) {
                return 'Invalid E-Mail';
              }
              return null;
            });
      }
    
      Widget _buildPasswordField() {
        return TextFormField(
            controller: password,
            obscureText: true,
            decoration: InputDecoration(labelText: 'Password'),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter your password';
              }
              return null;
            });
      }
    
      @override
      Widget build(BuildContext context) {
        return Card(
          child: Container(
            color: Colors.white,
            alignment: Alignment.center,
            child: Container(
              //color: Colors.green,
              width: 600,
              height: 300,
              child: Column(
                children: [
                  Form(
                    key: _formKey,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        _buildUsernameField(),
                        _buildPasswordField(),
                      ],
                    ),
                  ),
                  Column(
                    children: [
                      CheckboxListTile(title: Text('Remember me') ,
                          controlAffinity: ListTileControlAffinity.leading,
                          value: rememberMe, onChanged: (bool? value) {
                            setState(() {
                              rememberMe = value!;
                            });
                          }),
                      ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState!.validate()) {
                            print(username.text + "/" + password.text);
                            //didLoggedIn(username.text);
                            widget.didLoggedIn(username.text);
                          }
                        },
                        child: Text('Log me in'),
                      ),
                      Text('Forgot your password ?')
                    ],
                  )
                ],
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 类 LoginPage 扩展 StatefulWidget { final ValueChanged didLoggedIn;登录页面({this.didLoggedIn}); ---> this.didLoggedIn 抱怨:参数 'didLoggedIn' 的值不能为 'null',因为它的类型,但隐含的默认值是 'null'
    • 嗯...我刚刚添加了 LoginPage({required this.didLoggedIn});现在它起作用了!请编辑您的代码,以便我可以将您设置为求解器;) ty !!!
    【解决方案2】:

    你需要为 LoginPage 创建一个构造函数来保存这个类的回调,然后当你需要在 LoginPageState 中使用回调时,你使用 widget.callbackName() 或 widget.callbackName.call()。

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 2021-11-30
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 2022-06-27
      相关资源
      最近更新 更多