📜  Flutter – 登录屏幕(1)

📅  最后修改于: 2023-12-03 15:00:47.576000             🧑  作者: Mango

Flutter – 登录屏幕

Flutter是谷歌开发的一款跨平台移动应用开发框架,能够帮助我们快捷地构建漂亮且高性能的移动应用。一种最基本的移动应用功能就是用户的登录和注册,因此我们可以利用Flutter的强大功能来构建一个漂亮的登录/注册屏幕。

1. 背景

登录屏幕一般包括三个部分:一个logo或标题、两个输入框(一个用于输入用户名或电子邮件地址,另一个用于输入密码)和一个登录按钮。如果用户还没有账户,他们将会有机会点击一个链接或按钮来注册。

在Flutter中,我们可以利用现有的Widget来构建这些UI组件。Flutter的风格库很完善,提供了大量的Material Design和Cupertino Design Widget。

下面我们将通过示例代码,一步步实现一个漂亮的登录屏幕。

2. 界面设计

我们将使用Material Design Widget库来设计我们的登录屏幕。我们将设计一个简单的屏幕,包含了一个Logo、一个表单和一个登录按钮。我们还会添加一些显示或隐藏密码的选项。

Scaffold(
  resizeToAvoidBottomInset: false,
  body: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage('assets/login_background.png'),
        fit: BoxFit.cover,
      ),
    ),
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Container(
          margin: EdgeInsets.only(bottom: 32.0),
          child: Image.asset(
            'assets/login_logo.png',
            width: 160.0,
          ),
        ),
        LoginForm(),
      ],
    ),
  ),
)

上面的代码中,我们使用了一个Scaffold作为容器,并加入了一个带有Logo和表单的Column。

3. 表单设计

我们将创建一个新的StatefulWidget LoginForm来构建我们的登录表单。LoginForm包含了两个输入框和两个按钮。

class LoginForm extends StatefulWidget {
  @override
  _LoginFormState createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> {
  bool _isObscured = true;
  bool _showPwd = false;

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  String _email;
  String _password;

  Widget _buildEmailField() {
    return TextFormField(
      decoration: InputDecoration(
        labelText: '电子邮件地址',
        prefixIcon: Icon(Icons.email),
        filled: true,
        fillColor: Colors.white,
      ),
      keyboardType: TextInputType.emailAddress,
      validator: (String value) {
        if (value.isEmpty) {
          return '请输入电子邮件地址';
        }
      },
      onSaved: (String value) {
        _email = value;
      },
    );
  }

  Widget _buildPasswordField() {
    return TextFormField(
      obscureText: _isObscured,
      decoration: InputDecoration(
        labelText: '密码',
        prefixIcon: Icon(Icons.lock),
        suffixIcon: GestureDetector(
          onTap: () {
            setState(() {
              _showPwd = !_showPwd;
              _isObscured = !_isObscured;
            });
          },
          child: Icon(_showPwd ? Icons.visibility : Icons.visibility_off),
        ),
        filled: true,
        fillColor: Colors.white,
      ),
      keyboardType: TextInputType.text,
      validator: (String value) {
        if (value.isEmpty) {
          return '请输入密码';
        }
      },
      onSaved: (String value) {
        _password = value;
      },
    );
  }

  void _submitForm() {
    if (!_formKey.currentState.validate()) {
      return;
    }

    _formKey.currentState.save();

    // user login
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(horizontal: 32.0),
      child: Form(
        key: _formKey,
        child: Column(
          children: [
            _buildEmailField(),
            SizedBox(height: 16.0),
            _buildPasswordField(),
            SizedBox(height: 16.0),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: _submitForm,
                child: Text('登录'),
              ),
            ),
            SizedBox(height: 16.0),
            GestureDetector(
              onTap: () {
                Navigator.of(context)
                    .push(MaterialPageRoute(builder: (_) => RegisterPage()));
              },
              child: Text(
                '没有账号?点击这里注册!',
                style: TextStyle(
                  color: Colors.white,
                  decoration: TextDecoration.underline,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

上面的代码中,我们定义了一个_State类,表示了登录表单的状态。LoginForm包括了两个文本框、两个按钮和一些状态数据。

我们使用了一个Form来包装表单,并设置了一个全局的Key,以便于我们可以从_formKey.currentState获取表单数据。

和Flutter中其他的文本输入控件一样,我们使用了TextFormField来实现输入框。我们也使用了prefixIcon和suffixIcon来添加Icon。由于密码通常需要隐藏,我们用obscureText属性和一个_showPwd状态变量来控制密码是否可见。

4. 总结

漂亮的登录界面是App的重要组成部分之一。Flutter的Material Design库提供了许多好用的UI控件,可以快速构建一个漂亮的登录/注册界面。此外,我们可以自定义控件来满足我们的需求,并可以使用StatefulWidget来控制控件的状态。