Clicking login button returns Exception: BoxConstraints forces an infinite height

Viewed 19

I've been trying for a few days to figure out why the following exception is thrown when I run a flutter project and click the login button. Thought Flutter/Dart was to be "flexible"? There are no indicators of how to resolve this from the IDE or what I have tried below.

Exception: BoxConstraints forces an infinite height. These invalid constraints were provided to _RenderColoredBox's layout()

What I have tried:

I have tried specifying width to the scaffold which did not work, I then tried to use a constrained box and used the maxHeight: MediaQuery.of(context).size.height which did not work. I then removed the input fields except the button and that still did not work upon submission. I've also tried a number of examples as a last ditch attempt to resolve this, none of which were successful.

The login.dart file is below:

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

class LoginPage extends StatefulWidget {
  const LoginPage({Key, key}) : super(key: key);

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

class _LoginPageState extends State<LoginPage> {
  TextStyle style = const TextStyle(fontSize: 20.0);
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final RoundedLoadingButtonController _btnController =
  RoundedLoadingButtonController();


  bool _waiting = false;
  bool _buttonEnable = false;
  bool _isPasswordObscured = true;
  String loginError = "";

  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
  }

  void _clearEmailField() {
    _emailController.clear();
    setState(() {}); // update ui
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.

    List<Widget> _buildPage(BuildContext context) {
      final loginButton = RoundedLoadingButton(
          controller: _btnController,
          color: Colors.white,//Theme.of(context).primaryColor,
          onPressed: () async {
            FocusManager.instance.primaryFocus?.unfocus();
            setState(() {
              _waiting = true;
 
            });
             
            if(result) {
              Navigator.of(context).pushReplacementNamed('/unity');
            } else {
              setState(() {
                _btnController.reset();
                _waiting = false;
              });
            }
          },

          child: const Text(
            "Login",
            textAlign: TextAlign.center,
            style: TextStyle(color: Color(0xFF4C4184), fontWeight: FontWeight.bold, fontFamily: 'arial'),
          ));

      const emailForgot = Text(
        'Forgot your account?',
        textAlign: TextAlign.right,
        style: TextStyle(fontSize: 10),
      );

      final emailField = SizedBox(
          height: 55,
          child: TextFormField(
          controller: _emailController,
          obscureText: false,
          autocorrect: false,
          enableSuggestions: false,
          autofocus: false,
          keyboardType: TextInputType.emailAddress,
          style: const TextStyle(fontSize: 16),
          decoration: InputDecoration(
            filled: true,
            hintText: "Email",
            prefixIcon: const Icon(Icons.email_outlined, color: Colors.grey),
            suffixIcon: _emailController.text.isEmpty
              ? null
              : IconButton(
                  icon: const Icon(
                      Icons.clear,
                  ),
              onPressed: _clearEmailField,
              ),
            fillColor:
            contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
            focusedBorder: const OutlineInputBorder(
                borderSide: BorderSide(color: Colors.white),
                borderRadius: BorderRadius.all(Radius.circular(90))),
            enabledBorder: const OutlineInputBorder(
                borderSide: BorderSide(color: Colors.white),
                borderRadius: BorderRadius.all(Radius.circular(90))),
          ),
          onChanged: (e) {
            setState(() {

              _buttonEnable = e.isNotEmpty;
            });
          }),
      );


      final passwordField = SizedBox(
        height: 55,
        child: TextField(
          controller: _passwordController,
          obscureText: _isPasswordObscured,
          style: const TextStyle(fontSize: 16),
          decoration: InputDecoration(
            filled: true,
            hintText: "Password",
            prefixIcon: const Icon(Icons.lock_outline_rounded, color: Colors.grey),
            suffixIcon: _passwordController.text.isEmpty
              ? null
              : IconButton(
              icon: Icon(
                (_isPasswordObscured ? Icons.visibility : Icons.visibility_off),
                color: Colors.grey,
              ),
              onPressed: () {
                setState(() {
                  _isPasswordObscured = !_isPasswordObscured;
                });
              },
            ),
          ),
          onChanged: (e) {
            setState(() {
              _buttonEnable = e.isNotEmpty;
            });
          }),
      );

      final registerButton = Center(child:Container(
          padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
          child: TextButton(
            onPressed: () {
              Navigator.of(context).pushReplacementNamed('/register');
            },
            child: Text("no account, click here",
                textAlign: TextAlign.center,
                style: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold, fontSize: 10)),
          )
      )
      );
 
 
      List<Widget> eList = [];
      eList.add(Text(loginError,
          style: const TextStyle(fontSize: 10, color: Color(0xFFFFD5D5))));

      var errors = Column(children: eList);
 

      var page = SingleChildScrollView(
        child: Center(
          child: Padding(
            padding: const EdgeInsets.all(40.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Image.asset(
                  "assets/logo.png",
                  width: 400,
                ),
                const SizedBox(height: 100.0),
                emailField,
                const SizedBox(height: 35),
                passwordField,
                const SizedBox(height: 65),

                Flexible(
                    fit: FlexFit.loose,
                    child: Align(
                        alignment: FractionalOffset.bottomCenter,
                        child: Column(children: [loginButton, registerButton]))), 
              ],
            ),
          ),
        ),
      );

      var l = <Widget>[];
      l.add(page);

      if (_waiting) {
        var modal = Stack(
          children: const [
            Opacity(
              opacity: 0.3,
              child: ModalBarrier(dismissible: false, color: Colors.black),
            )
          ],
        );
        l.add(modal);
      }

      return l;
    }


 


    return Scaffold(
       resizeToAvoidBottomInset : false,
        body: Container(
          width: double.infinity,
          height: double.infinity,
          decoration: const BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/background.png"),
              fit: BoxFit.cover,
            ),
          ),

          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Stack(children: _buildPage(context))
            ]
          )
        ),
    );
  }
}
 
1 Answers

Finding the following post: BoxConstraints forces an infinite height

I refactored the Scaffold below to include a Flexible child SizedBox which resolved the issue.

    return Scaffold(
  resizeToAvoidBottomInset : false,
  body: Container(
    width: double.infinity,
    height: double.infinity,
    decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/login_account_background.png"),
        fit: BoxFit.cover,
      ),
    ),
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Flexible( //new
          child: SizedBox(
              height: double.infinity,
              child: Stack(children: _buildPage(context))),
        ),
      ],
    ),
  ),
);
Related