簡體   English   中英

Flutter Textformfield 錯誤消息下移下一個小部件

[英]Flutter Textformfield error message shifted down the next widget

我的文本表單字段有問題。 每當顯示錯誤消息時,它就會向下移動下面的下一個小部件...

我嘗試搜索如何為錯誤文本提供位置,以便在未顯示時不使用不存在的位置,但我沒有找到解決方案。

這是問題的屏幕截圖和代碼。

在此處輸入圖像描述

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);
            }
          }
      ),
    );
  }
}

登錄頁面

@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");
                    }
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    ),
);
  }
}

謝謝你的建議,

克里斯

嘗試用容器包裝 textformfield 並給它高度和寬度

嘗試用容器包裝 TextFormField 並為其指定高度和寬度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM