Pada kesempatan kali ini kami akan membuat sebuah tutorial tentang pembuatan form login di flutter. Pada pembuatan form login di flutter, kita akan menggunakan beberapa dependencies, seperti http dan shared_preferences, mari kita tambahkan. Pertama buka file pubspec.yaml. Lalu pada bagian dependencies, tambahkan nama dependencies dan versi yang diinginkan. Kurang lebih akan terlihat seperti ini

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  http: ^0.12.0+1
  modal_progress_hud : ^0.1.2
  shared_preferences: ^0.5.1+1

Kemudian jalankan flutter packages get

Anda dapat menemukan semua dependencies untuk dart atau flutter di sini https://pub.dartlang.org/.



Membuat form login di Flutter

Berikut script main.dart kami

import 'package:flutter/material.dart';
import 'pages/Login.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Task Management System',
        home: Scaffold(
            resizeToAvoidBottomPadding: true,
            body: LoginScreen()
        )
    );
  }
}

Kami tidak langsung memasukan isi dari script yang membuat form login di bagian body, melainkan kami membuat file lain lalu memanggilnya. Ini bertujuan agar script terlihat lebih rapih, setidaknya untuk kami. Lalu buat sebuah file di dalam folder pages dan simpan dengan nama Login.dart, pastikan folder pages anda di dalam folder lib.

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'MainPage.dart';

import 'dart:async';
import 'dart:convert';

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => new _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;
  bool _isInAsyncCall = false;
  bool _isLoggedIn = false;

  TextEditingController emailloginController = new TextEditingController();
  TextEditingController passwordloginController = new TextEditingController();

  @override
  void initState() {
    super.initState();
    getCredential();
  }

  Widget LoginPage() {
    return ModalProgressHUD(
        opacity: 0.5,
        dismissible: false,
        progressIndicator: CircularProgressIndicator(),
        child: Form(
            key: _formKey,
            autovalidate: _autoValidate,
            child: Container(
                height: MediaQuery.of(context).size.height,
                child: SingleChildScrollView(
                  child: new Column(
                    children: <Widget>[
                      Container(
                        padding: EdgeInsets.only(left:100.0,top: 100.0,right: 100.0,bottom: 25.0),
                        child: Center(
                          child: Icon(
                            Icons.work,
                            color:  Color.fromRGBO(58, 66, 86, 1.0),
                            size: 100.0,
                          ),
                        ),
                      ),
                      new Row(
                        children: <Widget>[
                          new Expanded(
                            child : Center (
                        child: new Text(
                        "Flutter",
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color:  Color.fromRGBO(58, 66, 86, 1.0),
                          fontSize: 22.0,
                        ),
                      ),
                            ),

                          ),
                        ],
                      ),
                      Divider(
                        height: 60.0,
                      ),
                      new Row(
                        children: <Widget>[
                          new Expanded(
                            child: new Padding(
                              padding: const EdgeInsets.only(left: 40.0),
                              child: new Text(
                                "Username",
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  color: Color.fromRGBO(58, 66, 86, 1.0),
                                  fontSize: 15.0,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                      new Container(
                        width: MediaQuery.of(context).size.width,
                        margin: const EdgeInsets.only(
                            left: 40.0, right: 40.0, top: 10.0),
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                          border: Border(
                            bottom: BorderSide(
                                color:  Color.fromRGBO(58, 66, 86, 1.0),
                                width: 0.5,
                                style: BorderStyle.solid),
                          ),
                        ),
                        padding: const EdgeInsets.only(left: 0.0, right: 10.0),
                        child: new Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: <Widget>[
                            new Expanded(
                              child: TextFormField(
                                controller: emailloginController,
                                validator: validateUsername,
                                obscureText: false,
                                textAlign: TextAlign.left,
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  hintText: 'Username',
                                  hintStyle: TextStyle(color: Colors.grey),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Divider(
                        height: 24.0,
                      ),
                      new Row(
                        children: <Widget>[
                          new Expanded(
                            child: new Padding(
                              padding: const EdgeInsets.only(left: 40.0),
                              child: new Text(
                                "Password",
                                style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  color: Color.fromRGBO(58, 66, 86, 1.0),
                                  fontSize: 15.0,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                      new Container(
                        width: MediaQuery.of(context).size.width,
                        margin: const EdgeInsets.only(
                            left: 40.0, right: 40.0, top: 10.0),
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                          border: Border(
                            bottom: BorderSide(
                                color: Color.fromRGBO(58, 66, 86, 1.0),
                                width: 0.5,
                                style: BorderStyle.solid),
                          ),
                        ),
                        padding: const EdgeInsets.only(left: 0.0, right: 10.0),
                        child: new Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: <Widget>[
                            new Expanded(
                              child: TextFormField(
                                controller: passwordloginController,
                                validator: validatePassword,
                                obscureText: true,
                                textAlign: TextAlign.left,
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  hintText: '*********',
                                  hintStyle: TextStyle(color: Colors.grey),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Divider(
                        height: 24.0,
                      ),
                      new Container(
                        width: MediaQuery.of(context).size.width,
                        margin: const EdgeInsets.only(
                            left: 30.0, right: 30.0, top: 20.0),
                        alignment: Alignment.center,
                        child: new Row(
                          children: <Widget>[
                            new Expanded(
                              child: new FlatButton(
                                shape: new RoundedRectangleBorder(
                                  borderRadius: new BorderRadius.circular(30.0),
                                ),
                                color:  Color.fromRGBO(58, 66, 86, 1.0),
                                onPressed: () => _validateInputs(),
                                child: new Container(
                                  padding: const EdgeInsets.symmetric(
                                    vertical: 20.0,
                                    horizontal: 20.0,
                                  ),
                                  child: new Row(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: <Widget>[
                                      new Expanded(
                                        child: Text(
                                          "LOGIN",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                              color: Colors.white,
                                              fontWeight: FontWeight.bold),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ))),
        inAsyncCall: _isInAsyncCall);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: MediaQuery.of(context).size.height,
        child: PageView(
          physics: new AlwaysScrollableScrollPhysics(),
          children: <Widget>[LoginPage()],
          scrollDirection: Axis.horizontal,
        ));
  }

  void _validateInputs() {
    if (_formKey.currentState.validate()) {
      setState(() {
        _isInAsyncCall = true;
        _login();
        _formKey.currentState.save();
      });
    } else {
      setState(() {
        _autoValidate = true;
        _isInAsyncCall = false;
      });
    }
  }
  String validatePassword(String value) {
    if (value.length < 6)
      return 'Minimal 6 karakter';
    else
      return null;
  }

  String validatePasswordSignup(String value) {
    if (value.length < 6)
      return 'Minimal 6 karakter';
    else
      return null;
  }

  String validateUsername(String value) {
    if (value.length < 5)
      return 'Minimal 5 karakter';
    else
      return null;
  }

  Future<dynamic> _login() async {
    final JsonDecoder _decoder = new JsonDecoder();
    try {
      final response = await http
          .post("http://192.168.1.8:84/project/api/login", body: {
        "username": emailloginController.text,
        "password": passwordloginController.text,
      });

      if (response.statusCode < 200 || response.statusCode > 300) {
        setState(() {
          _isInAsyncCall = false;
        });
        print(response.statusCode);
        throw new Exception('Failed to fetch data');
      } else {
        var datauser = _decoder.convert(response.body);
        if (datauser["error"]) {
          setState(() {
            _isInAsyncCall = false;
            showDialog(
                context: context,
                builder: (_) =>
                new AlertDialog(
                  content: new Text("Username atau password salah"),
                ));
          });
        } else {
          SharedPreferences prefs = await SharedPreferences.getInstance();
          setState(() {
            prefs.setString('UserId', datauser["userInfo"]["userid"]);
            prefs.setString('Fullname', datauser["userInfo"]["Fullname"]);
            prefs.setString('Email', datauser["userInfo"]["Email"]);
            prefs.setString('ProfilPict', datauser["userInfo"]["ProfilPict"]);
            prefs.setString('UserType', datauser["userInfo"]["usertype"]);
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => new MainPage()),
            );
            _isInAsyncCall = false;
          });
        }
      }
    } catch (e) {
      _isInAsyncCall = false;
      print(e);
      showDialog(
          context: context,
          builder: (_) =>
          new AlertDialog(
            content: new Text("Tidak terhubung dengan server"),
          ));
      setState(() {
        _isInAsyncCall = false;
      });
      return null;
    }
  }

  getCredential() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      if ( prefs.getString("UserId") != null){
        _isLoggedIn=  true;
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(builder: (context) => new MainPage()),
        );

      }else{
        _isLoggedIn =false;
      }
    });
  }
}

Kami akan menjelaskan sedikit tentang script untuk membuat form login di Flutter di atas. Pada bagian ini halam form login di buat

Widget LoginPage() {
  return ModalProgressHUD(
      opacity: 0.5,
      dismissible: false,
      progressIndicator: CircularProgressIndicator(),
      child: Form(
          key: _formKey,
          autovalidate: _autoValidate,
          child: Container(
              height: MediaQuery.of(context).size.height,
              child: SingleChildScrollView(
                child: new Column(
                  children: <Widget>[
                    Container(
                      padding: EdgeInsets.only(left:100.0,top: 100.0,right: 100.0,bottom: 25.0),
                      child: Center(
                        child: Icon(
                          Icons.work,
                          color:  Color.fromRGBO(58, 66, 86, 1.0),
                          size: 100.0,
                        ),
                      ),
                    ),
                    new Row(
                      children: <Widget>[
                        new Expanded(
                          child : Center (
                      child: new Text(
                      "Flutter",
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color:  Color.fromRGBO(58, 66, 86, 1.0),
                        fontSize: 22.0,
                      ),
                    ),
                          ),

                        ),
                      ],
                    ),
                    Divider(
                      height: 60.0,
                    ),
                    new Row(
                      children: <Widget>[
                        new Expanded(
                          child: new Padding(
                            padding: const EdgeInsets.only(left: 40.0),
                            child: new Text(
                              "Username",
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                color: Color.fromRGBO(58, 66, 86, 1.0),
                                fontSize: 15.0,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                    new Container(
                      width: MediaQuery.of(context).size.width,
                      margin: const EdgeInsets.only(
                          left: 40.0, right: 40.0, top: 10.0),
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        border: Border(
                          bottom: BorderSide(
                              color:  Color.fromRGBO(58, 66, 86, 1.0),
                              width: 0.5,
                              style: BorderStyle.solid),
                        ),
                      ),
                      padding: const EdgeInsets.only(left: 0.0, right: 10.0),
                      child: new Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: <Widget>[
                          new Expanded(
                            child: TextFormField(
                              controller: emailloginController,
                              validator: validateUsername,
                              obscureText: false,
                              textAlign: TextAlign.left,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: 'Username',
                                hintStyle: TextStyle(color: Colors.grey),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Divider(
                      height: 24.0,
                    ),
                    new Row(
                      children: <Widget>[
                        new Expanded(
                          child: new Padding(
                            padding: const EdgeInsets.only(left: 40.0),
                            child: new Text(
                              "Password",
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                color: Color.fromRGBO(58, 66, 86, 1.0),
                                fontSize: 15.0,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                    new Container(
                      width: MediaQuery.of(context).size.width,
                      margin: const EdgeInsets.only(
                          left: 40.0, right: 40.0, top: 10.0),
                      alignment: Alignment.center,
                      decoration: BoxDecoration(
                        border: Border(
                          bottom: BorderSide(
                              color: Color.fromRGBO(58, 66, 86, 1.0),
                              width: 0.5,
                              style: BorderStyle.solid),
                        ),
                      ),
                      padding: const EdgeInsets.only(left: 0.0, right: 10.0),
                      child: new Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: <Widget>[
                          new Expanded(
                            child: TextFormField(
                              controller: passwordloginController,
                              validator: validatePassword,
                              obscureText: true,
                              textAlign: TextAlign.left,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: '*********',
                                hintStyle: TextStyle(color: Colors.grey),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Divider(
                      height: 24.0,
                    ),
                    new Container(
                      width: MediaQuery.of(context).size.width,
                      margin: const EdgeInsets.only(
                          left: 30.0, right: 30.0, top: 20.0),
                      alignment: Alignment.center,
                      child: new Row(
                        children: <Widget>[
                          new Expanded(
                            child: new FlatButton(
                              shape: new RoundedRectangleBorder(
                                borderRadius: new BorderRadius.circular(30.0),
                              ),
                              color:  Color.fromRGBO(58, 66, 86, 1.0),
                              onPressed: () => _validateInputs(),
                              child: new Container(
                                padding: const EdgeInsets.symmetric(
                                  vertical: 20.0,
                                  horizontal: 20.0,
                                ),
                                child: new Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    new Expanded(
                                      child: Text(
                                        "LOGIN",
                                        textAlign: TextAlign.center,
                                        style: TextStyle(
                                            color: Colors.white,
                                            fontWeight: FontWeight.bold),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ))),
      inAsyncCall: _isInAsyncCall);
}

@override
Widget build(BuildContext context) {
  return Container(
      height: MediaQuery.of(context).size.height,
      child: PageView(
        physics: new AlwaysScrollableScrollPhysics(),
        children: <Widget>[LoginPage()],
        scrollDirection: Axis.horizontal,
      ));
}

Anda dapat melihat ModalProgressHUD, ModalProgressHUD merupakan dependencies yang kami gunakan untuk memunculkan efek loading ketika menekan tombol login. Lalu kemudian, Di bagian FlatButton tombol login kami memanggil fungsi validateInputs(), fungsi yang kami buat itu berguna untuk melihat apakah data input sudah lengkap atau pengisiannya sudah benar. Selain itu, kami juga menambahkan validator pada TextFormField diatas. Kegunaanya hampir sama seperti validateInputs() pada FlatButton tombol login. Berikut bagian validasi form yang kami maksud

void _validateInputs() {
  if (_formKey.currentState.validate()) {
    setState(() {
      _isInAsyncCall = true;
      _login();
      _formKey.currentState.save();
    });
  } else {
    setState(() {
      _autoValidate = true;
      _isInAsyncCall = false;
    });
  }
}
String validatePassword(String value) {
  if (value.length < 6)
    return 'Minimal 6 karakter';
  else
    return null;
}

String validatePasswordSignup(String value) {
  if (value.length < 6)
    return 'Minimal 6 karakter';
  else
    return null;
}

String validateUsername(String value) {
  if (value.length < 5)
    return 'Minimal 5 karakter';
  else
    return null;
}

Anda akan paham maksud dari script diatas.

Dan kemudian bagian proses login, pada proses ini kami menggunakan codeigniter sebagai backend. Kami mengirim dua parameter post, yaitu username dan password. Lalu, kami menerima data, kurang lebih seperti ini. Jika login salah , flutter akan menerima



{"error":true}

dan jika benar, data yang flutter terima seperti ini

{"error":false,"userInfo":{"userid":"U008","username":"Manager","password":"e10adc3949ba59abbe56e057f20f883e","lastlogindate":null,"usertype":"TP002","email":"[email protected]","user_flag":"1","BiodataId":"BI005","Fullname":"Manager","Address":"Jalan swasembada barat 8 no 42\r\nRT 001\/013","TelpNo":"08968787","ProfilPict":null,"login_id":"U008","placeofbirth":"","dateofbirth":"1994-10-01","gender":"1"}}

Jika login berhasil kami membuat session dengan Shared preferences.

Sekian artikel singkat tentang Membuat form login di Flutter, semoga bermanfaat. Jika ada pertanyaan , silahkan tinggalkan di bagian komentar.

Subscribe To Our Newsletter

Subscribe To Our Newsletter

Kami memberikan tutorial baru tiap harinya !!!

You have Successfully Subscribed!