Login UI in Flutter

The login screen based on my app Crosscheck Sports. Fluid UI and functional.

Sun, July 24 2022

jake hockey

Jake Landers

Developer and Creator

hey

This is a guide on how to make a simple compact (code-wise) log in screen in flutter.

Final Product

Watch Video (local link)

Create a Stateful Widget:

You will need two fields for this, a form key which controls the state of the form, and a bool to control whether to show the password text or not

1class Login extends StatefulWidget { 2 3 _LoginState createState() => _LoginState(); 4} 5 6class _LoginState extends State<Login> { 7 // key for form 8 final _formKey = GlobalKey<FormState>(); 9 10 // whether the password is hidden or not 11 bool _hidePass = true; 12 13 14 Widget build(BuildContext context) { 15 return Scaffold( 16 // app bar 17 appBar: AppBar( 18 title: Text("Login"), 19 backgroundColor: Colors.red, 20 ), 21 body: Text('Hello, World.') 22 ); 23 } 24} 25

Then, create your specific fields:

Email Field:

1// email field 2Widget _emailField(BuildContext context) { 3 return TextFormField( 4 decoration: const InputDecoration( 5 icon: Icon(Icons.person), 6 labelText: 'Email *', 7 ), 8 validator: (value) { 9 // chekc state of the field 10 if (!value.contains('@') || !value.contains('co')) { 11 // field does not have @ sign or a .co 12 return 'Please enter a valid email address'; 13 } 14 return null; 15 }, 16 ); 17} 18

Password Field:

1// password field 2Widget _passField(BuildContext context) { 3 return Row( 4 children: [ 5 Expanded( 6 child: TextFormField( 7 decoration: const InputDecoration( 8 icon: Icon(Icons.lock), 9 labelText: 'Password *', 10 ), 11 obscureText: _hidePass, 12 validator: (value) { 13 if (value.isEmpty) { 14 return 'Password cannot be blank'; 15 } 16 return null; 17 }, 18 ), 19 ), 20 IconButton( 21 padding: EdgeInsets.all(0), 22 onPressed: () { 23 _hidePass = !_hidePass; 24 setState(() {}); 25 }, 26 icon: Icon( 27 _hidePass ? Icons.remove_red_eye_outlined : Icons.remove_red_eye), 28 color: _hidePass 29 ? Colors.black.withOpacity(0.3) 30 : Colors.black.withOpacity(0.8), 31 ), 32 ], 33 ); 34} 35

Login Button:

1// login button 2Widget _loginButton(BuildContext context) { 3 // get screen size 4 var size = MediaQuery.of(context).size; 5 return FlatButton( 6 padding: EdgeInsets.all(0), 7 onPressed: () { 8 // make sure the form is valid 9 if (_formKey.currentState.validate()) { 10 // navigate to new page 11 Navigator.push( 12 context, 13 MaterialPageRoute( 14 builder: (context) => Scaffold( 15 body: Text('Second Page'), 16 ), 17 ), 18 ); 19 } 20 }, 21 child: Container( 22 height: 50, 23 width: size.width / 2, 24 decoration: BoxDecoration( 25 color: Colors.red, 26 borderRadius: BorderRadius.circular(10), 27 ), 28 child: Center( 29 child: Text('Login', style: TextStyle(color: Colors.white)), 30 ), 31 ), 32 // clip of button will not extend beyond border radius 33 shape: RoundedRectangleBorder( 34 borderRadius: BorderRadius.circular(10), 35 ), 36 ); 37} 38

Lastly, put it all together:

You can get creative with padding and columns to get spacing-like control with the column.

1 2Widget build(BuildContext context) { 3 return Scaffold( 4 // app bar 5 appBar: AppBar( 6 title: Text("Login"), 7 backgroundColor: Colors.red, 8 ), 9 body: Form( 10 key: _formKey, 11 child: Padding( 12 padding: const EdgeInsets.all(16), 13 child: Column( 14 children: [ 15 // email field 16 _emailField(context), 17 // password field with padding 18 Padding( 19 padding: const EdgeInsets.symmetric(vertical: 16), 20 child: _passField(context), 21 ), 22 // login button 23 _loginButton(context), 24 ], 25 ), 26 ), 27 ), 28 ); 29} 30

Source Code:

Github Link

Comments