In this post, we are going to learn how to build a beautiful login/signup (registration flow)for your app.

Project setup

Simply create a new project in flutter and give it the name flutterAuthUI.

Directory structure

Once the project is created, open it into Android Studio. We’re using Android studio because it has the most complete Flutter support (Dart syntax, code completion, debugging tools). By default, you should see the following directory structure:

  1. android - where Android-related files are stored. If you’ve done any sort of cross-platform mobile app development before, this, along with the ios folder should be pretty familiar.
  2. ios - where iOS-related files are stored.
  3. lib - This is where you’ll be working most of the time. By default, it contains a main. dart file, this is the entry point file of the Flutter app. we are going to create our own widget for login/signup here.
  4. test - this is where you put the unit testing code for the app. We won’t really be working on it in this tutorial.
  5. pubspec.yaml - this file defines the version and build number of your app. It’s also where you define your dependencies. If you’re coming from a web development background, this file has the same job description as the package.json file so you can define the external packages (from the Dart packages website) you want to use here.
  6.  

Note that I’ve skipped on other folders and files because most of the time you won’t really need to touch them.

Project Structure :

.idea //folder which holds the configuration for Android studio.
android //Android native app project and is used when building your Flutter application.
build //holding the compiled code of your Flutter application.
ios  //iOS native project which is used when building your Flutter application.
lib // lib folder the Dart files which contain the code of your Flutter application.
  components
  Screens
    Login
        components
            background.dart
            body.dart
        login_screen.dart
    Signup
       components
            background.dart
            body.dart
        signup_screen.dart
    Welcome
        components
            background.dart
            body.dart
        welcome_screen.dart
  constants.dart
  main.dart
test //Flutter application automated test when building.
.metadata //managed by Flutter automatically and is used to track properties of the Flutter project.
.packages //Flutter SDK and is used to contain a list of dependencies for your Flutter project.
.projectname.iml //This file is always named according to the project’s name and contains further settings of the Flutter project.Usually, this file is not changed by you and the content is managed by the Flutter SDK in an automated way.
pubspec.lock
pubspec.yaml

The pubspec.yaml file is the project’s configuration file you’ll use a lot when working with your Flutter project. This file contains:

  • general project settings like name, description, and version of the project
  •  project dependencies
  • assets (e.g. images) which should be available in your Flutter application

Create and run a simple Flutter app

  • Create a new Flutter app by running the following from the command line:
       flutter create <project name>
  • Create a new app Flutter app with package/bundle id  by running the following from the command line:
       flutter create --org com.wapptech <project name>
  • <project name> the directory is created, containing Flutter’s starter app. Enter this directory:
       cd my_app
  • To launch the app in the Simulator, ensure that the Simulator is running and enter:
      flutter run

in the lib folder create folders and file like a Project Structure after add components then screens.

  • create a constants.dart  file a in lib folder and add code.
import 'package:flutter/material.dart';

const kPrimaryColor = Color(0xFF01579B);
const kPrimaryLightColor = Color(0xFFF1E6FF);

  • after that create  already_have_an_account_acheck.dart, rounded_button.dart, rounded_input_field.dart, rounded_password_field.dart and text_field_container.dart  files and add code.

already_have_an_account_acheck.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/constants.dart';

class AlreadyHaveAnAccountCheck extends StatelessWidget {
final bool login;
final Function press;
const AlreadyHaveAnAccountCheck({
Key key,
this.login = true,
this.press,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
login ? "Don’t have an Account ? " : "Already have an Account ? ",
style: TextStyle(color: kPrimaryColor),
),
GestureDetector(
onTap: press,
child: Text(
login ? "Sign Up" : "Sign In",
style: TextStyle(
color: kPrimaryColor,
fontWeight: FontWeight.bold,
),
),
)
],
);
}
}

rounded_button.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/constants.dart';

class RoundedButton extends StatelessWidget {
final String text;
final Function press;
final Color color, textColor;
const RoundedButton({
Key key,
this.text,
this.press,
this.color = kPrimaryColor,
this.textColor = Colors.white,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
width: size.width * 0.8,
child: ClipRRect(
borderRadius: BorderRadius.circular(29),
child: FlatButton(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
color: color,
onPressed: press,
child: Text(
text,
style: TextStyle(color: textColor),
),
),
),
);
}
}

rounded_input_field.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/components/text_field_container.dart';
import 'package:flutterAuthUI/constants.dart';

class RoundedInputField extends StatelessWidget {
final String hintText;
final IconData icon;
final ValueChanged<String> onChanged;
const RoundedInputField({
Key key,
this.hintText,
this.icon = Icons.person,
this.onChanged,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return TextFieldContainer(
child: TextField(
onChanged: onChanged,
cursorColor: kPrimaryColor,
decoration: InputDecoration(
icon: Icon(
icon,
color: kPrimaryColor,
),
hintText: hintText,
border: InputBorder.none,
),
),
);
}
}

rounded_password_field.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/components/text_field_container.dart';
import 'package:flutterAuthUI/constants.dart';

class RoundedPasswordField extends StatelessWidget {
final ValueChanged<String> onChanged;
const RoundedPasswordField({
Key key,
this.onChanged,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return TextFieldContainer(
child: TextField(
obscureText: true,
onChanged: onChanged,
cursorColor: kPrimaryColor,
decoration: InputDecoration(
hintText: "Password",
icon: Icon(
Icons.lock,
color: kPrimaryColor,
),
border: InputBorder.none,
),
),
);
}
}

text_field_container.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/constants.dart';

class TextFieldContainer extends StatelessWidget {
final Widget child;
const TextFieldContainer({
Key key,
this.child,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
width: size.width * 0.8,
decoration: BoxDecoration(
color: kPrimaryLightColor,
borderRadius: BorderRadius.circular(29),
),
child: child,
);
}
}
  • after that create a Welcome screen in Screens/Welcome/welcome_screen.dart and components.

welcome_screen.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Welcome/components/body.dart';

class WelcomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Body(),
);
}
}

Welcome/components/background.dart

import 'package:flutter/material.dart';

class Background extends StatelessWidget {
final Widget child;
const Background({
Key key,
@required this.child,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
height: size.height,
width: double.infinity,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned(
top: 0,
left: 0,
child: Image.asset(
"assets/images/main_top.png",
width: size.width * 0.3,
),
),
Positioned(
bottom: 0,
left: 0,
child: Image.asset(
"assets/images/main_bottom.png",
width: size.width * 0.2,
),
),
child,
],
),
);
}
}

Welcome/components/body.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Login/login_screen.dart';
import 'package:flutterAuthUI/Screens/Signup/signup_screen.dart';
import 'package:flutterAuthUI/Screens/Welcome/components/background.dart';
import 'package:flutterAuthUI/components/rounded_button.dart';
import 'package:flutterAuthUI/constants.dart';
import 'package:flutter_svg/svg.dart';

class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
// This size provide us total height and width of our screen
return Background(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"WELCOME TO EDU",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.05),
SvgPicture.asset(
"assets/icons/chat.svg",
height: size.height * 0.45,
),
SizedBox(height: size.height * 0.05),
RoundedButton(
text: "LOGIN",
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginScreen();
},
),
);
},
),
RoundedButton(
text: "SIGN UP",
color: kPrimaryLightColor,
textColor: Colors.black,
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return SignUpScreen();
},
),
);
},
),
],
),
),
);
}
}
  • after that create a Login screen in Screens/Welcome/login_screen.dart and components.

login_screen.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Login/components/body.dart';

class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Body(),
);
}
}

Login/components/background.dart

import 'package:flutter/material.dart';

class Background extends StatelessWidget {
final Widget child;
const Background({
Key key,
@required this.child,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;=
return Container(
width: double.infinity,
height: size.height,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned(
top: 0,
left: 0,
child: Image.asset(
"assets/images/main_top.png",
width: size.width * 0.35,
),
),
Positioned(
bottom: 0,
right: 0,
child: Image.asset(
"assets/images/login_bottom.png",
width: size.width * 0.4,
),
),
child,
],
),
);
}
}

Login/components/body.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Login/components/background.dart';
import 'package:flutterAuthUI/Screens/Signup/signup_screen.dart';
import 'package:flutterAuthUI/components/already_have_an_account_acheck.dart';
import 'package:flutterAuthUI/components/rounded_button.dart';
import 'package:flutterAuthUI/components/rounded_input_field.dart';
import 'package:flutterAuthUI/components/rounded_password_field.dart';
import 'package:flutter_svg/svg.dart';

class Body extends StatelessWidget {
const Body({
Key key,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Background(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"LOGIN",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.03),
SvgPicture.asset(
"assets/icons/login.svg",
height: size.height * 0.35,
),
SizedBox(height: size.height * 0.03),
RoundedInputField(
hintText: "Your Email",
onChanged: (value) {},
),
RoundedPasswordField(
onChanged: (value) {},
),
RoundedButton(
text: "LOGIN",
press: () {},
),
SizedBox(height: size.height * 0.03),
AlreadyHaveAnAccountCheck(
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return SignUpScreen();
},
),
);
},
),
],
),
),
);
}
}
  • after that create a Signup screen in Screens/Welcome/signup_screen.dart and components.

signup_screen.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Signup/components/body.dart';

class SignUpScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Body(),
);
}
}

Signup/components/background.dart

import 'package:flutter/material.dart';

class Background extends StatelessWidget {
final Widget child;
const Background({
Key key,
@required this.child,
}) : super(key: key);

@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Container(
height: size.height,
width: double.infinity,
// Here i can use size.width but use double.infinity because both work as a same
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned(
top: 0,
left: 0,
child: Image.asset(
"assets/images/signup_top.png",
width: size.width * 0.35,
),
),
Positioned(
bottom: 0,
left: 0,
child: Image.asset(
"assets/images/main_bottom.png",
width: size.width * 0.25,
),
),
child,
],
),
);
}
}

Signup/components/body.dart

import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Login/login_screen.dart';
import 'package:flutterAuthUI/Screens/Signup/components/background.dart';
import 'package:flutterAuthUI/components/already_have_an_account_acheck.dart';
import 'package:flutterAuthUI/components/rounded_button.dart';
import 'package:flutterAuthUI/components/rounded_input_field.dart';
import 'package:flutterAuthUI/components/rounded_password_field.dart';
import 'package:flutter_svg/svg.dart';

class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Background(
child: SingleChildScrollView,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"SIGNUP",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: size.height * 0.03),
SvgPicture.asset(
"assets/icons/signup.svg",
height: size.height * 0.35,
),
RoundedInputField(
hintText: "Your Email",
onChanged: (value) {},
),
RoundedPasswordField(
onChanged: (value) {},
),
RoundedButton(
text: "SIGNUP",
press: () {},
),
SizedBox(height: size.height * 0.03),
AlreadyHaveAnAccountCheck(
login: false,
press: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginScreen();
},
),
);
},
)
],
),
),
);
]
}
}
  • last step open  lib/main.dart file and add this code:
import 'package:flutter/material.dart';
import 'package:flutterAuthUI/Screens/Welcome/welcome_screen.dart';
import 'constants.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Auth',
theme: ThemeData(
primaryColor: kPrimaryColor,
scaffoldBackgroundColor: Colors.white,
),
home: WelcomeScreen(),
);
}
}

Please run code and check UI done in your android and ios devices.

About the author
Code solution

info@codesolution.co.in

Discussion
  • 0 comments

Add comment To Login
Add comment