Zimme
Zimme

Reputation: 125

Error text increases TextFormField height which leads to overflow

So i have a few TextFormFields inside scrollable column and it works fine, until error text appears. Because it causes bottom overflow. The desired behavior is button that just jumps up and don’t cause overflow. I have tried to put textfield inside a container with fixed height but after error text appear it just shrinked textfield

Form _buildForm(BuildContext context, BoxConstraints constraints) {
print(constraints);
return Form(
  key: _form,
  child: SingleChildScrollView(
    child: ConstrainedBox(
      constraints: BoxConstraints(
          minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
      child: IntrinsicHeight(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              padding: const EdgeInsets.only(top: 48, bottom: 32),
              child: Text(
                'Sign Up',
                style: AppTheme.theme.textTheme.headline3
                    .copyWith(color: AppColors.black),
              ),
            ),
            LabeledTextField(
              margin: EdgeInsets.only(bottom: 16),
              fieldName: 'Email',
              decoration: InputDecoration(hintText: '[email protected]'),
              textInputAction: TextInputAction.next,
              onFieldSubmitted: (_) {
                FocusScope.of(context).requestFocus(_userNameFocusNode);
              },
              onSaved: (val) => _authData["login"] = val,
              validator: FormValidators.emailValidator,
              autovalidateMode: AutovalidateMode.onUserInteraction,
            ),
            LabeledTextField(
              margin: EdgeInsets.only(bottom: 16),
              fieldName: 'User Name',
              decoration: InputDecoration(hintText: 'alexexample...'),
              textInputAction: TextInputAction.next,
              onFieldSubmitted: (_) {
                FocusScope.of(context).requestFocus(_passwordFocusNode);
              },
              onSaved: (val) => _authData["username"] = val,
              validator: FormValidators.isRequiredValidator,
              autovalidateMode: AutovalidateMode.onUserInteraction,
            ),
            LabeledTextField(
              fieldName: 'Password',
              focusNode: _passwordFocusNode,
              obscureText: true,
              decoration: InputDecoration(hintText: 'Type in...'),
              onSaved: (val) => _authData["password"] = val,
              validator: FormValidators.passwordValidator,
              autovalidateMode: AutovalidateMode.onUserInteraction,
            ),
            Spacer(),
            AuthButtons(
              mode: AuthMode.signup,
              saveForm: _saveForm,
            ),
          ],
        ),
      ),
    ),
  ),
);

  }



@override
  Widget build(BuildContext context) {
    return Scaffold(
      //resizeToAvoidBottomInset: false,
      appBar: CustomAppBar(
        preferredSize: Size.fromHeight(64),
        title: 'title',
      ),
      body: Padding(
        padding: const EdgeInsets.only(left: 16, right: 16),
        child: LayoutBuilder(
          builder: (context, constraints) => _buildForm(context, constraints),
        ),
      ),
    );
  }

LabeledTextField is basically just a textFormField with Text widget before it

class _LabeledTextFieldState extends State<LabeledTextField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: widget.margin,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            widget.fieldName,
            style: AppTheme.theme.textTheme.caption
                .copyWith(color: AppColors.darkGrey),
          ),
          TextFormField(
            initialValue: widget.initialValue,
            textInputAction: widget.textInputAction,
            focusNode: widget.focusNode,
            onSaved: widget.onSaved,
            onChanged: widget.onChanged,
            validator: widget.validator,
            onFieldSubmitted: widget.onFieldSubmitted,
            autovalidateMode: widget.autovalidateMode,
            obscureText: widget.obscureText,
            decoration: widget.decoration,
          ),
        ],
      ),
    );
  }
}

Upvotes: 2

Views: 1899

Answers (2)

Arijeet
Arijeet

Reputation: 1213

Wrap your Column with SingleChildScrollView

class _LabeledTextFieldState extends State<LabeledTextField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: widget.margin,
      child: SingleChildScrollView(
       physics: BouncingScrollPhysics(),  // u can ignore this if u want
        child : Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            widget.fieldName,
            style: AppTheme.theme.textTheme.caption
                .copyWith(color: AppColors.darkGrey),
          ),
          TextFormField(
            initialValue: widget.initialValue,
            textInputAction: widget.textInputAction,
            focusNode: widget.focusNode,
            onSaved: widget.onSaved,
            onChanged: widget.onChanged,
            validator: widget.validator,
            onFieldSubmitted: widget.onFieldSubmitted,
            autovalidateMode: widget.autovalidateMode,
            obscureText: widget.obscureText,
            decoration: widget.decoration,
          ),
        ],
      ),
      ),
    );
  }
}

Upvotes: 0

Farhan Aslam
Farhan Aslam

Reputation: 31

You can try expanded instead of a container as a parent widget or use wrap as a parent widget on your text field.

Upvotes: 1

Related Questions