Bismillaahirrohmaanirrohiim…
Setelah kita berhasil membuat splash screen, selanjutnya kita akan membuat form login dan register di flutter.
Sebelum melanjutkan, pastikan anda telah mengikuti artikel sebelumnya.
Tutorial ini adalah hasil dari implementasi login screen yang telah dibuat oleh whisnuys di github.
Langsung saja, ikuti langkah-langkah di bawah ini:
1. Buat sebuah file di dalam folder lib, theme.dart
import 'package:flutter/material.dart'; Color primaryBlue = Color(0xff2972ff); Color colorLight = Color(0xfffbfbfb); Color textBlack = Color(0xff222222); Color textGrey = Color(0xff94959b); Color textWhiteGrey = Color(0xfff1f1f5); TextStyle heading2 = TextStyle( fontSize: 24, fontWeight: FontWeight.w700, ); TextStyle heading5 = TextStyle( fontSize: 18, fontWeight: FontWeight.w600, ); TextStyle heading6 = TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ); TextStyle regular16pt = TextStyle( fontSize: 16, fontWeight: FontWeight.w400, );
File theme.dart digunakan untuk menyimpan variabel-variabel warna, ukuran, dan lain-lain. Tujuannya untuk memudahkan jika suatu saat ingin mengganti theme tinggal mengubah nilai tersebut di satu tempat saja. Fungsi lainnya adalah agar warna, ukuran font, dll bisa “SERAGAM” disemua halaman aplikasi.
2. Download Font dan Images
Download fonts dan images kemudian masukkan ke dalam folder assets. (Link download ada di bawah).
Jangan lupa mengedit file pubspec.yaml di bagian ini:
assets: - assets/images/ # - assets/images/splash.png fonts: - family: Lato fonts: - asset: assets/fonts/Lato-Regular.ttf weight: 400 - asset: assets/fonts/Lato-SemiBold.ttf weight: 600 - asset: assets/fonts/Lato-Bold.ttf weight: 700
3. Buat folder “widgets” di dalam folder “lib”
4. Buat file “custom_checkbox.dart” di dalam folder “widgets”
Widget Checkbox ini akan dipanggil dan digunakan saat nanti membuat halaman yang ada checkbox-nya. Berikut kodenya:
import 'package:flutter/material.dart'; import 'package:belajarflutter/theme.dart'; class CustomCheckbox extends StatefulWidget { const CustomCheckbox({ Key? key }) : super(key: key); @override _CustomCheckboxState createState() => _CustomCheckboxState(); } class _CustomCheckboxState extends State<CustomCheckbox> { bool isChecked = false; @override Widget build(BuildContext context) { return GestureDetector( onTap: () { setState(() { isChecked = !isChecked; }); }, child: Container( decoration: BoxDecoration( color: isChecked ? primaryBlue : Colors.transparent, borderRadius: BorderRadius.circular(4), border: isChecked ? null : Border.all(color: textGrey, width: 1.5) ), width: 20, height: 20, child: isChecked ? Icon(Icons.check, size: 20,color: Colors.white,) : null, ), ); } }
5. Buat file “primary_button.dart” di dalam folder “widgets”
Widget ini nanti dipanggil saat ingin membuat button dengan variabel warna dan ukuran yang dapat ditentukan. Berikut kodenya:
import 'package:flutter/material.dart'; import 'package:belajarflutter/theme.dart'; class CustomPrimaryButton extends StatelessWidget { final Color buttonColor; final String textValue; final Color textColor; const CustomPrimaryButton({ this.buttonColor=Colors.black, this.textValue='', this.textColor=Colors.black }); @override Widget build(BuildContext context) { return Material( borderRadius: BorderRadius.circular(14), elevation: 0, child: Container( height: 56, decoration: BoxDecoration( color: buttonColor, borderRadius: BorderRadius.circular(14) ), child: Material( color: Colors.transparent, child: InkWell( onTap: () {}, borderRadius: BorderRadius.circular(14), child: Center( child: Text( textValue, style: heading5.copyWith(color: textColor), ), ), ), ), ), ); } }
6. Membuat halaman register
Setelah kita mempunyai assets, widget, dan theme, saatnya membuat halaman register.
Buat file register_view.dart di dalam folder lib, kodenya seperti berikut:
import 'package:flutter/material.dart'; import 'package:belajarflutter/theme.dart'; import 'package:belajarflutter/widgets/custom_checkbox.dart'; import 'package:belajarflutter/widgets/primary_button.dart'; class RegisterPage extends StatefulWidget { const RegisterPage({ Key? key }) : super(key: key); @override _RegisterPageState createState() => _RegisterPageState(); } class _RegisterPageState extends State<RegisterPage> { bool passwordVisible = false; bool passwordConfirmVisible = false; void togglePassword() { setState(() { passwordVisible = !passwordVisible; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Padding( padding: EdgeInsets.fromLTRB(24, 40, 24, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'APP Flutter\nRegister', style: heading2.copyWith(color: textBlack), ), SizedBox( height: 20, ), Image.asset( 'assets/images/accent.png', width: 99, height: 4, ) ], ), SizedBox(height: 48,), Form( child: Column( children: [ Container( decoration: BoxDecoration( color: textWhiteGrey, borderRadius: BorderRadius.circular(14) ), child: TextFormField( decoration: InputDecoration( hintText: 'Email', hintStyle: heading6.copyWith(color: textGrey), border: OutlineInputBorder( borderSide: BorderSide.none ) ), ), ), SizedBox(height: 32,), Container( decoration: BoxDecoration( color: textWhiteGrey, borderRadius: BorderRadius.circular(14) ), child: TextFormField( obscureText: !passwordVisible, decoration: InputDecoration( hintText: 'Password', hintStyle: heading6.copyWith(color: textGrey), suffixIcon: IconButton( color: textGrey, splashRadius: 1, icon: Icon(passwordVisible ? Icons.visibility_outlined : Icons.visibility_off_outlined), onPressed: togglePassword, ), border: OutlineInputBorder(borderSide: BorderSide.none) ), ), ), SizedBox(height: 32,), Container( decoration: BoxDecoration( color: textWhiteGrey, borderRadius: BorderRadius.circular(14) ), child: TextFormField( obscureText: !passwordConfirmVisible, decoration: InputDecoration( hintText: 'Password Confirmation', hintStyle: heading6.copyWith(color: textGrey), suffixIcon: IconButton( color: textGrey, splashRadius: 1, icon: Icon(passwordConfirmVisible ? Icons.visibility_outlined : Icons.voice_over_off_outlined), onPressed: () { setState(() { passwordConfirmVisible = !passwordConfirmVisible; }); }, ), border: OutlineInputBorder(borderSide: BorderSide.none) ), ), ) ], ) ), SizedBox(height: 32,), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ CustomCheckbox(), SizedBox(width: 12,), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'By creating an account, you agree to our', style: regular16pt.copyWith(color: textGrey), ), Text( 'Term & Condition', style: regular16pt.copyWith(color: primaryBlue), ) ], ) ], ), SizedBox(height: 32,), CustomPrimaryButton( buttonColor: primaryBlue, textValue: 'Register', textColor: Colors.white, ), SizedBox(height: 50,), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Already have an account? ', style: regular16pt.copyWith(color: textGrey), ), GestureDetector( onTap: () { Navigator.pop(context); }, child: Text( 'Login', style: regular16pt.copyWith(color: primaryBlue), ), ) ], ) ], ), ) ), ); } }
7. Membuat halaman Login
Sama seperti halaman register, untuk membuat halaman login, buatlah file dengan nama login_view.dart di dalam folder lib.
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:belajarflutter/register_view.dart'; import 'package:belajarflutter/theme.dart'; import 'package:belajarflutter/widgets/custom_checkbox.dart'; import 'package:belajarflutter/widgets/primary_button.dart'; class LoginPage extends StatefulWidget { const LoginPage({ Key? key }) : super(key: key); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { bool passwordVisible = false; void togglePassword() { setState(() { passwordVisible = !passwordVisible; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SafeArea( child: Padding( padding: EdgeInsets.fromLTRB(24, 40, 24, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'APP Flutter\nLogin', style: heading2.copyWith(color: textBlack), ), SizedBox(height: 20,), Image.asset( 'assets/images/accent.png', width: 99, height: 4, ) ], ), SizedBox(height: 48,), Form( child: Column( children: [ Container( decoration: BoxDecoration( color: textWhiteGrey, borderRadius: BorderRadius.circular(14) ), child: TextFormField( decoration: InputDecoration( hintText: 'Email', hintStyle: heading6.copyWith(color: textGrey), border: OutlineInputBorder(borderSide: BorderSide.none) ), ), ), SizedBox(height: 32,), Container( decoration: BoxDecoration( color: textWhiteGrey, borderRadius: BorderRadius.circular(14) ), child: TextFormField( obscureText: !passwordVisible, decoration: InputDecoration( hintText: 'Password', hintStyle: heading6.copyWith(color: textGrey), suffixIcon: IconButton( color: textGrey, splashRadius: 1, icon: Icon(passwordVisible ? Icons.visibility_outlined : Icons.visibility_off_outlined), onPressed: togglePassword, ), border: OutlineInputBorder( borderSide: BorderSide.none ) ), ), ) ], ) ), SizedBox(height: 32,), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ CustomCheckbox(), SizedBox(width: 12,), Text('Remember me', style: regular16pt,) ], ), SizedBox(height: 32,), CustomPrimaryButton( buttonColor: primaryBlue, textValue: 'Login', textColor: Colors.white, ), SizedBox(height: 24,), Center( child: Text( 'Or', style: heading6.copyWith(color: textGrey), ), ), SizedBox(height: 24,), CustomPrimaryButton( buttonColor: colorLight, textValue: 'Login with Google', textColor: textBlack, ), SizedBox(height: 50,), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Belum punya akun? ', style: regular16pt.copyWith(color: textGrey), ), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => RegisterPage() ) ); }, child: Text( 'Register', style: regular16pt.copyWith(color: primaryBlue), ), ) ], ) ], ), ), ), ); } }
8. Modifikasi halaman splashscreen_view.dart
Setelah splash screen muncul, kita ingin mengarahkan/redirect ke halaman login, jadi ubah file splashscreen_view.dart di bagian openSplashScreenn() menjadi seperti di bawah ini:
openSplashScreen() async { var durasiSplash = const Duration(seconds: 2); return Timer(durasiSplash, () { //pindah ke halaman login Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (_) { //return HomePage(); return LoginPage(); }) ); }); }
Pastikan di atas ada import package:
import 'package:belajarflutter/login_view.dart';
Setelah semuanya beres, coba jalankan dengan cara klik menu Run=>Start Debugging. Maka Setelah aplikasi terbuka, muncul splash screen kemudian ke halaman login. Klik link register, maka akan diarahkan ke halaman register. Mudah bukan.
Jika ada kendala atau kesulitan, silahkan tinggalkan di komentar.
Terimakasih, semoga bermanfaat.
Sumber dan assets: https://github.com/whisnuys/simple-login-page