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