The login screen based on my app Crosscheck Sports. Fluid UI and functional.
Sun, July 24 2022
Jake Landers
Developer and Creator
Table of Contents
This is a guide on how to make a simple compact (code-wise) log in screen in flutter.
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
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
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
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
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