0

如果我犯了错误,这是我的第一个问题,请纠正我:)

编码:Android Studio 语言为:Flutter/Dart

问题:如何在单独的 toast/snack bar/flush bar 的 textformfield 下方显示错误消息?

问题视频链接:https ://youtu.be/4hJtR11o1GU

代码:

import 'package:flutter/material.dart';
  import 'package:flutter/services.dart';
  //import 'package:video_player/video_player.dart';

  class LoginForm extends StatefulWidget {
    LoginForm(this.submitFn, this.isLoading);

    final bool isLoading;
    final void Function(
        String email,
        String password,
        String mobile,
        bool  isLogin,
        BuildContext ctx,
        ) submitFn;

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

  class _LoginFormState extends State<LoginForm> {
  final _formKey = GlobalKey<FormState>();
  var _isLogin = true;
  String _userEmail = '';
  String _userPassword = '';
  String _userMobile = '';

  void _trySubmit() {
    final isValid = _formKey.currentState.validate();
    FocusScope.of(context).unfocus();
    if (isValid) {
      _formKey.currentState.save();
      widget.submitFn(
        _userEmail.trim(),
        _userPassword.trim(),
        _userMobile.trim(),
        _isLogin,
        context
      );
    }
  }



  Widget _buildEmailTF() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Container(
          alignment: Alignment.centerLeft,
          height: 50.0,
          child: TextFormField(
            key: ValueKey('email'),
            validator: (value) { if (value.isEmpty || !value.contains('@'))  {return
              'enter a valid email';} return null;},
            keyboardType: TextInputType.emailAddress,
            style: TextStyle(color: Colors.white, fontFamily: 'OpenSans',),
            decoration: InputDecoration(
              isDense: true,
              hintText: 'username@xyz.com',
              hintStyle: TextStyle(color: Colors.white, ),
              contentPadding: EdgeInsets.only(top: 14.0),
              errorMaxLines: 1,
              errorText: 'Null',
              errorStyle: TextStyle(
                color: Colors.transparent,
                fontSize: 0,
              ),
              prefixIcon: Icon(
                Icons.email,
                color: Colors.orange ,
              ),
            ),
            onSaved:(value){_userEmail = value;},
          ),
        ),
      ],
    );
  }
  Widget _buildMobileTF() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Container(
          alignment: Alignment.centerLeft,
          height: 50.0,
          child: TextFormField(
            key: ValueKey('mobile'),
            validator: (value) { if (value.isEmpty || !value.contains('91') || value.length > 12  || value.length < 12)  {
              return '';} return null;},
            keyboardType: TextInputType.number,
            style: TextStyle(
              color: Colors.white,
              fontFamily: 'OpenSans',
            ),
            decoration: InputDecoration(
              errorMaxLines: 1,
              errorText: 'Null',
              errorStyle: TextStyle(
                color: Colors.transparent,
                fontSize: 0,
              ),
              hintText: '91 xxx-xxx-xxxx',
              hintStyle: TextStyle(color: Colors.white, ),
              border: InputBorder.none,
              contentPadding: EdgeInsets.only(top: 14.0),
              prefixIcon: Icon(
                Icons.phone_android,
                color: Colors.orange,
              ),
            ),
            onSaved:(value){_userMobile = value;},
          ),
        ),
      ],
    );
  }
  Widget _buildPasswordTF() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        SizedBox(height: 10.0),
        Container(
          alignment: Alignment.centerLeft,
          height: 60.0,
          child: TextFormField(
            key: ValueKey('password'),
            validator: (value) {if (value.isEmpty || value.length < 7) {
                return '';} return null;},
            obscureText: true,
            style: TextStyle(
              color: Colors.white,
              fontFamily: 'OpenSans',
            ),
            decoration: InputDecoration(
                errorMaxLines: 1,
                errorText: 'Null',
                errorStyle: TextStyle(
                  color: Colors.transparent,
                  fontSize: 0,
                ),
              contentPadding: EdgeInsets.only(top: 14.0),
              prefixIcon: Icon(
                Icons.lock,
                color: Colors.orange,
              ),
              hintText: 'Password',
                hintStyle: TextStyle(color: Colors.white, )
            ),
            onSaved:(value){
              _userPassword = value;
            },
          ),
        ),
      ],
    );
  }
  Widget _buildLoginBtn() {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 25.0),
      width: double.infinity,
      child: RaisedButton(
        onPressed: _trySubmit,
        elevation: 5.0,
        padding: EdgeInsets.all(15.0),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(30.0),
        ),
        color: Colors.white,
        child: Text(_isLogin ? 'Login In' : 'Sign Up',
          style: TextStyle(
            color: Colors.orange,
            letterSpacing: 1.5,
            fontSize: 18.0,
            fontWeight: FontWeight.bold,
            fontFamily: 'OpenSans',
          ),
        ),
      ),
    );
  }
  Widget _buildSignUpWithText() {
    return Column(
      children: <Widget>[
        FlatButton(
          textColor: Theme.of(context).primaryColor,
          child: Text(_isLogin ? 'Sign Up With An Email Account' : 'I Already Have An Account',
          style: TextStyle(
            color: Colors.orange,
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
          ),
          onPressed: () {
           setState(() {
             _isLogin = !_isLogin;
           });

          },
          ),
        SizedBox(height: 20.0),
        Text(
          '- OR -',
          style: TextStyle(
            color: Colors.white,
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
        ),

      ],
    );
  }
  Widget _buildSocialBtn(Function onTap, AssetImage logo) {
    return GestureDetector(
      onTap: (){
        setState(() {
        });
        _isLogin = !_isLogin;
      },
      child: Container(
        height: 60.0,
        width: 60.0,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: Colors.white,
          boxShadow: [
            BoxShadow(
              color: Colors.black26,
              offset: Offset(0, 2),
              blurRadius: 6.0,
            ),
          ],
          image: DecorationImage(
            image: logo,
          ),
        ),
      ),
    );
  }
  Widget _buildSocialBtnRow() {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 30.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          _buildSocialBtn(
                () => print('Sign Up with Google'),
            AssetImage(
              'assets/logos/google.jpg',
            ),
          ),
        ],
      ),
    );
  }
  Widget _buildHomeChefSignUp() {
    return GestureDetector(onTap: () => print('Chef\'s Sign Up Process'),
      child: RichText(
          text: TextSpan(
              children: [
                TextSpan(text: 'Passionate About Cooking ? ',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 12.0,
                    fontWeight: FontWeight.w400,
                  ),),
                TextSpan(text: 'Join Us',
                  style: TextStyle(
                    color: Colors.orange,
                    fontSize: 12.0,
                    fontWeight: FontWeight.w400,
                  ),),
      ])),
    );
  }

  @override
  Widget build(BuildContext context) {
    //Keeps Back Ground Fixed even with Keyboard Opened
    return Scaffold(resizeToAvoidBottomPadding: false,
      //Top Status Bar Overlay Dark or Light
      body: AnnotatedRegion<SystemUiOverlayStyle>(value: SystemUiOverlayStyle.light,
        child: GestureDetector(onTap: ()=>FocusScope.of(context).unfocus(),
          //Main Tree holding All the necessary Containers
          child: Stack(children: <Widget>[
            //Holds the background Video
            Container(),
            //Creates a black overlay to the background
            Container(
              height: double.infinity,
              color:  Colors.black.withAlpha(120),),
            //Hold the Login Form
            Container(
              height:    double.infinity,
              child:     SingleChildScrollView(
                physics: AlwaysScrollableScrollPhysics(),
                padding: EdgeInsets.symmetric(horizontal: 40.0, vertical: 100.0,),
                child:   Form(
                  key:   _formKey,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                    Text(
                      'Mother\'s Kitchen',
                      style: TextStyle(
                        color: Colors.orange,
                        fontFamily: 'MomsFonts',
                        fontSize: 40.0,
                        fontWeight: FontWeight.bold,),),
                    SizedBox(height: 10.0),
                    Text(
                      'Mumbai\'s First & Only Home Cooked Delivery Service',
                      style: TextStyle(
                        color: Colors.orange,
                        fontFamily: 'OpenSans',
                        fontSize: 12.0,
                        fontWeight: FontWeight.bold,),),
                    SizedBox(height: 30.0),
                    _buildEmailTF(),
                    SizedBox(height: 10.0,),
                    if(!_isLogin)
                      _buildMobileTF(),
                    _buildPasswordTF(),
                    if(widget.isLoading)
                      Column(
                        children: <Widget>[
                          SizedBox(height: 10.0),
                          CircularProgressIndicator(),
                        ],
                      ),
                    if(!widget.isLoading)
                    _buildLoginBtn(),
                    _buildSignUpWithText(),
                    _buildSocialBtnRow(),
                      _buildHomeChefSignUp(),
                    ],),
                ),),
            ),],
          ),),
      ),);
  }
  }

4

0 回答 0