简体   繁体   中英

Flutter Textformfield error message shifted down the next widget

I have an issue with my textformfield. Whenever the error message shows, it shifted down the next widget below...

I try to search how to give a placement for the error text to no take a placement that does not exist when it is not shown, but I didn't find the solution.

Here are the screenshot and the code of the issue.

在此处输入图像描述

class AuthForm extends StatefulWidget {
  final bool isPassword;
  final IconData prefixIcon;
  final String hintText;
  late bool isPasswordVisible = isPassword;
  final bool isCalendar;
  final TextEditingController controller;
  final bool isDropDown;
  final bool isPhone;
  final String? Function(String?)? validator;

  AuthForm({Key? key, this.isPassword = false, required this.prefixIcon, required this.hintText,
    this.isCalendar = false, required this.controller, this.isDropDown = false, this.isPhone = false, required this.validator}) : super(key: key);

  @override
  State<AuthForm> createState() => _AuthFormState();
}

class _AuthFormState extends State<AuthForm> {

  @override
  void initState() {
    super.initState();
    if (widget.isPhone){
      getCountryCode();
    }
  }

  start () async {
    await CountryCodes.init();
  }
  Locale? getCountryCode () {
    start();
    final Locale? deviceLocale = CountryCodes.getDeviceLocale();
    final CountryDetails details = CountryCodes.detailsForLocale();
    return deviceLocale;
  }

  DateTime selectedDate = DateTime(2000,1);
  Future<void> _selectDate(BuildContext context) async {
    final DateTime? picked = await showDatePicker(
        context: context,
        initialDate: selectedDate,
        firstDate: DateTime(1950, 1),
        lastDate: DateTime.now());
    if (picked != null && picked != selectedDate) {
      setState(() {
        selectedDate = picked;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return widget.isDropDown ? const DropDownBar() :
    SizedBox(
      width: 70.w,
      child: TextFormField(
          validator: widget.validator,
          keyboardType: widget.isPhone ? TextInputType.phone : TextInputType.text,
          inputFormatters: [DialCodeFormatter()],
          controller: widget.controller,
          textAlign: TextAlign.center,
          obscureText: widget.isPasswordVisible,
          style: Theme.of(context).textTheme.bodyText2,
          decoration: InputDecoration(
            contentPadding: EdgeInsets.fromLTRB(0, 2.3.h, 0, 0),
            hintText : widget.hintText,
            hintStyle: Theme.of(context).textTheme.bodyText1,
            enabledBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Theme.of(context).splashColor,
                width: 0.13.w,
              ),
            ),
            errorStyle: Theme.of(context).textTheme.headline6,
            prefixIcon: Container(
              width: 0,
              alignment: const Alignment(-0.99, 0.5),
              child: Icon(
                widget.prefixIcon,
                color: Theme.of(context).primaryColor,
                size: 6.w,
              ),
            ),
            suffixIcon: Visibility(
              visible: widget.isPassword,
              //Maintain the space where the widget is even if it is hid
              maintainAnimation: true,
              maintainState: true,
              maintainSize: true,
              child: InkWell(
                highlightColor : Colors.transparent,
                splashColor: Colors.transparent,
                child: Container(
                  width: 0,
                  alignment: const Alignment(0.99, 0.5),
                  child: Icon(
                    widget.isPasswordVisible ? Icons.visibility : Icons.visibility_off,
                    color: Theme.of(context).primaryColor,
                    size: 6.w,
                  ),
                ),
                onTap: () {
                  setState(() {
                    widget.isPasswordVisible = !widget.isPasswordVisible;
                  });
                },
              ),
            ),
          ),
          onTap: () async {
            if (widget.isCalendar){
              //Dismiss the keyboard
              FocusScope.of(context).requestFocus(FocusNode());
              //Call the calendar
              await _selectDate(context);
              widget.controller.text = DateFormat('dd-MM-yyyy').format(selectedDate);
            }
          }
      ),
    );
  }
}

Login Page

@override
  Widget build(BuildContext context) {
    return BlocListener<InternetCubit, InternetState>(
      listener: (context, state) {
        if (state is InternetDisconnected) {
          showAlertBox(context);
        }
      },
    child: Form(
      key: _formkey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(
            height: 6.h,
          ),
          Text(
            "Flexmes",
            style: Theme.of(context).textTheme.headline1,
          ),
          SizedBox(
            height: 8.h,
          ),
          AuthForm(
            prefixIcon: Icons.email_outlined,
            hintText: "Email",
            controller: emailController,
            nextFocusNode: passwordNode,
            validator: MultiValidator([
              RequiredValidator(errorText: 'Email is required'),
              EmailValidator(errorText: 'Enter a valid email address'),
            ]),
          ),
          SizedBox(
            height: 3.h,
          ),
          AuthForm(
            isPassword: true,
            prefixIcon: Icons.lock_rounded,
            hintText: "Password",
            controller: passwordController,
            currentFocusNode: passwordNode,
            validator: MultiValidator([
              RequiredValidator(errorText: 'Password is required'),
              MinLengthValidator(6, errorText: 'Password must be at least 6 digits long'),
              PatternValidator(r'(?=.*?[#?!@$%^&*-])', errorText: 'Passwords must have at least one special character')
            ]),
          ),
          SizedBox(
            height: 4.5.h,
          ),
          SizedBox(
            width: 70.w,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                CustomCheckbox(
                  iconColor: Colors.black,
                  activeColor: const Color.fromARGB(255, 3, 218, 197),
                ),
                SizedBox(
                  width: 3.w,
                ),
                Text(
                  "Remember me",
                  style: Theme.of(context).textTheme.bodyText2,
                )
              ],
            ),
          ),
          SizedBox(
            height: 4.5.h,

          ),
          AuthButton(
            text: "Log In",
            onPressed: (){
              if (isInternetDisconnected(context)){
                showAlertBox(context);
              } else{
                if (_formkey.currentState!.validate()){
                  AuthenticationAPI(auth: FirebaseAuth.instance).signInWithEmail(emailController.text, passwordController.text);
                  //return navigation
                }

              }
            }
          ),
          SizedBox(
            height: 3.2.h,
          ),
          ClickableText(
            text: "Forgot Password ?",
            onPressed: () {
              if (isInternetDisconnected(context)){
                showAlertBox(context);
              } else{
                //return navigation
              }
            },
          ),
          SizedBox(
            height: 3.2.h,
          ),
          const AuthDivider(
            text: "OR",
          ),
          SizedBox(
            height: 2.h,
          ),
          SizedBox(
            width: 70.w,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ClickableImage(
                  imagePath: "assets/images/icon/Facebook.png",
                  width: 23.w,
                  onPressed: () {
                    null;
                  },
                ),
                ClickableImage(
                  imagePath: "assets/images/icon/Instagram.png",
                  width: 23.w,
                  onPressed: () {
                    null;
                  },
                ),
                ClickableImage(
                  imagePath: "assets/images/icon/Tiktok.png",
                  width: 23.w,
                  onPressed: () {
                    null;
                  },
                ),
              ],
            ),
          ),
          SizedBox(
            height: 4.h,
          ),
          SizedBox(
            width: 70.w,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  "Don't have an account ? ",
                  style: Theme.of(context).textTheme.bodyText2,
                ),
                ClickableText(
                  text: 'Sign up Now !',
                  onPressed: () {
                    if (isInternetDisconnected(context)){
                      showAlertBox(context);
                    } else{
                      Navigator.of(context).pushNamed("/signup1");
                    }
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    ),
);
  }
}

Thanks for your suggestion,

Chris

try wrapping textformfield with container and giving it height and width

Try wrapping TextFormField with container and give it height and width.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM