Categories: Flutter

Membuat form login dan register di flutter dengan mudah

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

Bagikan
rasupe

View Comments

Recent Posts

CPU usage tinggi pada server

Bismillaahirrohmaanirrohiim... Untuk mendeteksi cpu usage tinggi memang perkara rumit, adakalanya karena codingan bermasalah, akses ke…

2 weeks ago

Membersihkan log mongodb yang besar

Bismillaahirrohmaanirrohiim... Jika tidak dirawat dan dicek berkala, log mongodb akan semakin membesar. Bahkan sampai menghabiskan…

4 weeks ago

Cara mengakses gps di HP dengan javascript

Bismillaahirrohmaanirrohiim... Jika kita membuat website yang digunakan untuk memantau lokasi HP client, maka kita memerlukan…

4 months ago

Menghitung jarak dua titik koordinat dengan php dan javascript

Bismillaahirrohmaanirrohiim... Kali ini kita akan mencoba menerapkan rumus trigonometeri dari formula haversine, yang digunakan untuk…

4 months ago

Kemasan cleo botol kecil sering bikin tangan terluka

Bismillaahirrohmaanirrohiim... Disini saya akan berbagi pengalaman tentang susahnya membuka tutup botol cleo kecil ukuran 220ml.…

4 months ago

Solusi InsCek pada meteran PLN

Bismillaahirrohmaanirrohiim... Kali ini saya akan berbagi pengalaman tentang mati lampu yang disebabkan oleh permasalahan arus…

4 months ago