Home > Software engineering >  Flutter blank screen when using Form with TextFormField
Flutter blank screen when using Form with TextFormField

Time:07-23

I am making a login screen like I have many times, but I keep running into this issue and don't know what to do. There are two TextFormFields, inside a Column, inside a Form like this

  Widget loginForm() {
    return Form(
        key: _loginFormKey,
        child: Flexible(
          child: Column(
            children: [
              const SizedBox(
                height: 10,
              ),
              TextFormField(
                controller: _emailController,
                decoration: const InputDecoration(
                  suffix: Icon(Icons.mail_outline_rounded, color: Colors.red),
                  labelText: "Email",
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(8)),
                      borderSide: BorderSide(color: Color(0xFF7FCCDC))),
                ),
                validator: (email) {
                  return null;
                },
              ),
              const SizedBox(
                height: 10,
              ),
              TextFormField(
                controller: _passController,
                obscureText: true,
                decoration: const InputDecoration(
                  suffix: Icon(Icons.lock_outline, color: Colors.red),
                  labelText: "Password",
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.all(Radius.circular(8)),
                      borderSide: BorderSide(color: Color(0xFF7FCCDC))),
                ),
                validator: (password) {
                  return null;
                },
              ),
            ],
          ),
        ),
    );
  }

This widget is put in the following scaffold:

        Padding(
          padding:
              const EdgeInsets.only(top: 175, left: 35, right: 35, bottom: 50),
          child: Center(
            child: Container(
              height: 300,
              width: 250,
              decoration: BoxDecoration(
                color: Color(0xFFFCFBF4).withOpacity(0.5),
                borderRadius: BorderRadius.circular(20),
              ),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  SizedBox(height: 15),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text('Sign In',
                          style: TextStyle(
                              fontSize: 20, color: Color(0xFF6B6FAB))),
                    ],
                  ),
                  Row(
                    children: [
                      loginForm(),
                    ],
                  )
                ],
              ),
            ),
          ),
        )

When the loginForm() widget is removed, the screen launches as it should. However, when it is there, the screen launches blank white. I've tried taking all the customization out of the TextFormFields and putting them in containers with restricted sizes but that didn't change anything. This is no different from the way I've done the forms in the past and there are no errors. What is the issue?

import 'package:flutter/material.dart';

class SignInScreen extends StatefulWidget {
  const SignInScreen({Key? key}) : super(key: key);

  @override
  State<SignInScreen> createState() => _SignInScreenState();
}

class _SignInScreenState extends State<SignInScreen> {
  final _loginFormKey = GlobalKey<FormState>();

  Widget background() {
    return Container(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      decoration: const BoxDecoration(
          gradient: LinearGradient(colors: [
        Color(0xFF7157A0),
        Color(0xFF6B6FAB),
        Color(0xFF6C74B4),
        Color(0xFF697CB4)
      ], stops: [
        0.25,
        0.5,
        0.75,
        1
      ], begin: Alignment.topCenter)),
    );
  }

  final _emailController = TextEditingController();
  final _passController = TextEditingController();

  Widget loginForm() {
    return Form(
      key: _loginFormKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const SizedBox(
            height: 10,
          ),
          TextFormField(
            controller: _emailController,
            decoration: const InputDecoration(
              suffix: Icon(Icons.mail_outline_rounded, color: Colors.red),
              labelText: "Email",
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8)),
                  borderSide: BorderSide(color: Color(0xFF7FCCDC))),
            ),
            validator: (email) {
              return null;
            },
          ),
          const SizedBox(
            height: 10,
          ),
          TextFormField(
            controller: _passController,
            obscureText: true,
            decoration: const InputDecoration(
              suffix: Icon(Icons.lock_outline, color: Colors.red),
              labelText: "Password",
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8)),
                  borderSide: BorderSide(color: Color(0xFF7FCCDC))),
            ),
            validator: (password) {
              return null;
            },
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: [
        background(),
        Padding(
          padding: const EdgeInsets.only(top: 55),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.asset('assets/logo.png', height: 100),
              SizedBox(width: 5),
              Text('GLOBE',
                  style: TextStyle(
                      fontSize: 40,
                      fontWeight: FontWeight.bold,
                      color: Color(0xFF7FCCDC)))
            ],
          ),
        ),
        Padding(
          padding:
              const EdgeInsets.only(top: 175, left: 35, right: 35, bottom: 50),
          child: Container(
            decoration: BoxDecoration(
              color: Color(0xFFFCFBF4).withOpacity(0.5),
              borderRadius: BorderRadius.circular(20),
            ),
            child: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  SizedBox(height: 15),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text('Sign In',
                          style:
                              TextStyle(fontSize: 20, color: Color(0xFF6B6FAB))),
                    ],
                  ),
                  loginForm()
                ],
              ),
            ),
          ),
        ),
      ],
    ));
  }
}

CodePudding user response:

class MyHome extends StatelessWidget {
  MyHome({Key? key}) : super(key: key);
  final _loginFormKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          background(context),
          Padding(
            padding: const EdgeInsets.only(top: 55),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: const [
                // Image.asset('assets/logo.png', height: 100),
                SizedBox(width: 5),
                Text('GLOBE',
                    style: TextStyle(
                        fontSize: 40,
                        fontWeight: FontWeight.bold,
                        color: Color(0xFF7FCCDC)))
              ],
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(
                top: 175, left: 35, right: 35, bottom: 50),
            child: Center(
              child: Container(
                decoration: BoxDecoration(
                  color: const Color(0xFFFCFBF4).withOpacity(0.5),
                  borderRadius: BorderRadius.circular(20),
                ),
                child: Column(
                  children: [
                    const SizedBox(height: 15),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: const [
                        Text('Sign In',
                            style: TextStyle(
                                fontSize: 20, color: Color(0xFF6B6FAB))),
                      ],
                    ),
                    loginForm(),
                  ],
                ),
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget loginForm() {
    return Form(
      key: _loginFormKey,
      child: Flexible(
        child: Column(
          children: [
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              controller: _emailController,
              decoration: const InputDecoration(
                suffix: Icon(Icons.mail_outline_rounded, color: Colors.red),
                labelText: "Email",
                border: OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(8)),
                    borderSide: BorderSide(color: Color(0xFF7FCCDC))),
              ),
              validator: (email) {
                return null;
              },
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              controller: _passController,
              obscureText: true,
              decoration: const InputDecoration(
                suffix: Icon(Icons.lock_outline, color: Colors.red),
                labelText: "Password",
                border: OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(8)),
                    borderSide: BorderSide(color: Color(0xFF7FCCDC))),
              ),
              validator: (password) {
                return null;
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget background(context) {
    return Container(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      decoration: const BoxDecoration(
        gradient: LinearGradient(colors: [
          Color(0xFF7157A0),
          Color(0xFF6B6FAB),
          Color(0xFF6C74B4),
          Color(0xFF697CB4)
        ], stops: [
          0.25,
          0.5,
          0.75,
          1
        ], begin: Alignment.topCenter),
      ),
    );
  }
}

enter image description here

CodePudding user response:

Remove flexible here and add mainAxisSize min to the column widget. A flexible inside a column without bounds will break the ui

return Form(
        key: _loginFormKey,
      //child: Flexible( //remove this widget
          child: Column(
            mainAxisSize: MainAxisSize.min,
          )
);

Your layout should be something like this

Scaffold(
  body: Container(
   width: MediaQuery.of(context).size.width,
   height: MediaQuery.of(context).height,
    decoration: BoxDecoration(
     image: DecorationImage(
       image: AssetImage('image path here'),
     )
    )
   child: Column(
    children: []//place widgets here
   )
  )
)

Now if the widgets are long enough to move over the height of device wrap the column with SingleChildScrollView

EDIT

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: SignInScreen());
  }
}

class SignInScreen extends StatefulWidget {
  const SignInScreen({Key? key}) : super(key: key);

  @override
  State<SignInScreen> createState() => _SignInScreenState();
}

class _SignInScreenState extends State<SignInScreen> {
  final _loginFormKey = GlobalKey<FormState>();

  final _emailController = TextEditingController();
  final _passController = TextEditingController();

  Widget loginForm() {
    return Form(
      key: _loginFormKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const SizedBox(
            height: 10,
          ),
          TextFormField(
            controller: _emailController,
            decoration: const InputDecoration(
              suffix: Icon(Icons.mail_outline_rounded, color: Colors.red),
              labelText: "Email",
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8)),
                  borderSide: BorderSide(color: Color(0xFF7FCCDC))),
            ),
            validator: (email) {
              return null;
            },
          ),
          const SizedBox(
            height: 10,
          ),
          TextFormField(
            controller: _passController,
            obscureText: true,
            decoration: const InputDecoration(
              suffix: Icon(Icons.lock_outline, color: Colors.red),
              labelText: "Password",
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(8)),
                  borderSide: BorderSide(color: Color(0xFF7FCCDC))),
            ),
            validator: (password) {
              return null;
            },
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      decoration: const BoxDecoration(
          gradient: LinearGradient(colors: [
        Color(0xFF7157A0),
        Color(0xFF6B6FAB),
        Color(0xFF6C74B4),
        Color(0xFF697CB4)
      ], stops: [
        0.25,
        0.5,
        0.75,
        1
      ], begin: Alignment.topCenter)),
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(top: 55),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Image.network(
                    'https://thumbs.dreamstime.com/b/jpg-file-icon-logo-element-illustration-design-155443757.jpg',
                    height: 100),
                SizedBox(width: 5),
                Text('GLOBE',
                    style: TextStyle(
                        fontSize: 40,
                        fontWeight: FontWeight.bold,
                        color: Color(0xFF7FCCDC)))
              ],
            ),
          ),
          Expanded(
            child: Center(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 35),
                child: Container(
                  margin: EdgeInsets.only(bottom: 40),
                  decoration: BoxDecoration(
                    color: Color(0xFFFCFBF4).withOpacity(0.5),
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      SizedBox(height: 15),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text('Sign In',
                              style: TextStyle(
                                  fontSize: 20, color: Color(0xFF6B6FAB))),
                        ],
                      ),
                      loginForm()
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    ));
  }
}
  • Related