Cara Cepat Membuat CRUD dengan Flutter dan SQFlite
Halo semuanya, kembali lagi di tulisan saya. Pada kesempatan kali ini kita akan belajar membuat CRUD flutter dan SQflite dengan studi kasus aplikasi kontak. Penasaran?, ayo ikuti pembahasannya di bawah ini.


Pada tutorial kali ini, kita akan membuat project sederhana. Kita akan mengimplementasikan proses create, read, update, dan delete dengan database SQFlite. Jadi nantinya kita akan membuat tampilan listview di halaman utama yang menampilkan info kontak dari setiap orang, berisi nama, email, no telpon, dan company. Lalu terdapat floating action button yang berfungsi untuk menambah data nantinya. Kita akan belajar banyak hal di tutorial ini. Apa saja?

    ⦿ Membuat daftar/list dengan Listview Builder
    ⦿ Konsep Model,
    ⦿ Menampilkan, Menyimpan, Meng-update, dan delete data dengan SQFlite
    ⦿ Menampilkan Alert dengan Alert Dialog
    ⦿ Melakukan perpindahan halaman dengan Navigator
    ⦿ Dan masih banyak lainnya.....

Cukup banyak ilmu yang bisa kita dapatkan dari tutorial singkat ini, dan sangat berguna untuk improvisasi pembuatan aplikasi berbasis flutter yang lebih kompleks lagi. Dan jika kalian ingin melihat hasil akhirnya, silahkan langsung scroll saja ke bagian paling bawah tutorial ini.


Baca Artikel Lain ✨
📰 1. Cara Membuat Pencarian pada ListView Flutter read more
📰 2. Cara Mudah Install dan Menggunakan SQLite di Laravel read more
📰 3. Cara Switch Tampilan dari ListView Menjadi GridView di Flutter read more



Cara Membuat CRUD dengan Flutter dan SQFlite

1. Buatlah sebuah project flutter dengan nama flutter_contact.

2. Buka pubspec.yaml, lalu copy library SQFlite di bawah ini lalu paste di bawah cupertino icon. 

sqflite: ^2.0.0+3

Ikuti instruksinya seperti gambar di bawah ini. Setelah ditambahkan, silahkan save untuk mengunduh library SQFlite.

Cara CRUD Flutter dan SQFlite
Import Library SQFlite


3. Buatlah struktur folder project kita seperti gambar di bawah ini. Terdapat folder model berisi file kontak.dart, terdapat folder database berisi file db_helper.dart, dan terdapat 3 file lain diantaranya main.dart, list_kontak.dart dan form_kontak.dart.

CRUD Flutter dan SQFlite
Struktur Folder 



4. Silahkan buka file model/kontak.dart. Lalu copy dan paste script di bawah ini.
    


// ignore_for_file: file_names, unnecessary_this, prefer_collection_literals

class Kontak{
    int? id;
String? name;
String? mobileNo;
String? email;
String? company;

Kontak({this.id, this.name, this.mobileNo, this.email, this.company});

Map<String, dynamic> toMap() {
    var map = Map<String, dynamic>();

if (id != null) {
map['id'] = id;
}
map['name'] = name;
map['mobileNo'] = mobileNo;
map['email'] = email;
map['company'] = company;

return map;
    }

Kontak.fromMap(Map<String, dynamic> map) {
    this.id = map['id'];
this.name = map['name'];
this.mobileNo = map['mobileNo'];
this.email = map['email'];
this.company = map['company'];
    }
}


5. Selanjutnya buka file database/db_helper.dart. Copy dan paste script di bawah ini. File ini memuat fungsi-fungsi database. Seperti pembuatan database, fungsi penyimpanan, fungsi tampil, fungsi update, dan fungsi delete. Fungsi-fungsi ini akan dipanggil saat dibutuhkan nantinya.
        


// ignore_for_file: non_constant_identifier_names


//dbhelper ini dibuat untuk
//membuat database, membuat tabel, proses insert, read, update dan delete


import 'package:flutter_contact/model/kontak.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:path/path.dart';

class DbHelper {
    static final DbHelper _instance = DbHelper._internal();
static Database? _database;

//inisialisasi beberapa variabel yang dibutuhkan
final String tableName = 'tableKontak';
final String columnId = 'id';
final String columnName = 'name';
final String columnMobileNo = 'mobileNo';
final String columnEmail = 'email';
final String columnCompany = 'company';

DbHelper._internal();
factory DbHelper() => _instance;

//cek apakah database ada
Future<Database?> get _db async {
    if (_database != null) {
    return _database;
}
_database = await _initDb();
    return _database;
}

Future<Database?> _initDb() async {
    String databasePath = await getDatabasesPath();
String path = join(databasePath, 'kontak.db');

return await openDatabase(path, version: 1, onCreate: _onCreate);
}

//membuat tabel dan field-fieldnya
Future<void> _onCreate(Database db, int version) async {
    var sql = "CREATE TABLE $tableName($columnId INTEGER PRIMARY KEY, "
    "$columnName TEXT,"
"$columnMobileNo TEXT,"
"$columnEmail TEXT,"
"$columnCompany TEXT)";
await db.execute(sql);
    }

//insert ke database
Future<int?> saveKontak(Kontak kontak) async {
    var dbClient = await _db;
return await dbClient!.insert(tableName, kontak.toMap());
    }

//read database
Future<List?> getAllKontak() async {
    var dbClient = await _db;
var result = await dbClient!.query(tableName, columns: [
    columnId,
columnName,
columnCompany,
columnMobileNo,
columnEmail
        ]);

return result.toList();
    }

//update database
Future<int?> updateKontak(Kontak kontak) async {
    var dbClient = await _db;
    return await dbClient!.update(tableName, kontak.toMap(), where: '$columnId = ?', whereArgs: [kontak.id]);
}

//hapus database
Future<int?> deleteKontak(int id) async {
    var dbClient = await _db;
return await dbClient!.delete(tableName, where: '$columnId = ?', whereArgs: [id]);
}
}


6. Selanjutnya buka main.dart. Hapus isi di dalamnya dan ganti dengan script di bawah ini.
    


// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, unused_element, non_constant_identifier_names, avoid_types_as_parameter_names, avoid_function_literals_in_foreach_calls, unused_local_variable, unused_import, use_key_in_widget_constructors

import 'package:flutter/material.dart';
import 'database/db_helper.dart';
import 'form_kontak.dart';
import 'list_kontak.dart';
import 'model/kontak.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: ListKontakPage(),
);
}
}



7. Selanjutnya buka file list_kontak.dart. Copy script di bawah ini dan paste ke dalam file tersebut. File ini akan membuat list/daftar yang menampilkan seluruh data dari database nantinya, tidak lupa juga kita tambahkan fungsi tampil data dari db_helper.dart
    


// ignore_for_file: prefer_const_literals_to_create_immutables, prefer_const_constructors, avoid_function_literals_in_foreach_calls, non_constant_identifier_names, unused_element, unused_local_variable, sized_box_for_whitespace

import 'package:flutter/material.dart';
import 'form_kontak.dart';

import 'database/db_helper.dart';
import 'model/kontak.dart';

class ListKontakPage extends StatefulWidget {
const ListKontakPage({ Key? key }) : super(key: key);

@override
_ListKontakPageState createState() => _ListKontakPageState();
}

class _ListKontakPageState extends State<ListKontakPage> {
List<Kontak> listKontak = [];
DbHelper db = DbHelper();

@override
void initState() {
//menjalankan fungsi getallkontak saat pertama kali dimuat
_getAllKontak();
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(

appBar: AppBar(
title: Center(
child: Text("Kontak App"),
),
),
body: ListView.builder(
itemCount: listKontak.length,
itemBuilder: (context, index) {
Kontak kontak = listKontak[index];
return Padding(
padding: const EdgeInsets.only(
top: 20
),
child: ListTile(
leading: Icon(
Icons.person,
size: 50,
),
title: Text(
'${kontak.name}'
),
subtitle: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 8,
),
child: Text("Email: ${kontak.email}"),
),
Padding(
padding: const EdgeInsets.only(
top: 8,
),
child: Text("Phone: ${kontak.mobileNo}"),
),
Padding(
padding: const EdgeInsets.only(
top: 8,
),
child: Text("Company: ${kontak.company}"),
)
],
),
trailing:
FittedBox(
fit: BoxFit.fill,
child: Row(
children: [
// button edit
IconButton(
onPressed: () {
_openFormEdit(kontak);
},
icon: Icon(Icons.edit)
),
// button hapus
IconButton(
icon: Icon(Icons.delete),
onPressed: (){
//membuat dialog konfirmasi hapus
AlertDialog hapus = AlertDialog(
title: Text("Information"),
content: Container(
height: 100,
child: Column(
children: [
Text(
"Yakin ingin Menghapus Data ${kontak.name}"
)
],
),
),
//terdapat 2 button.
//jika ya maka jalankan _deleteKontak() dan tutup dialog
//jika tidak maka tutup dialog
actions: [
TextButton(
onPressed: (){
_deleteKontak(kontak, index);
Navigator.pop(context);
},
child: Text("Ya")
),
TextButton(
child: Text('Tidak'),
onPressed: () {
Navigator.pop(context);
},
),
],
);
showDialog(context: context, builder: (context) => hapus);
},
)
],
),
),
),
);
}),
//membuat button mengapung di bagian bawah kanan layar
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: (){
_openFormCreate();
},
),

);
}

//mengambil semua data Kontak
Future<void> _getAllKontak() async {
//list menampung data dari database
var list = await db.getAllKontak();

//ada perubahanan state
setState(() {
//hapus data pada listKontak
listKontak.clear();

//lakukan perulangan pada variabel list
list!.forEach((kontak) {

//masukan data ke listKontak
listKontak.add(Kontak.fromMap(kontak));
});
});
}

//menghapus data Kontak
Future<void> _deleteKontak(Kontak kontak, int position) async {
await db.deleteKontak(kontak.id!);
setState(() {
listKontak.removeAt(position);
});
}

// membuka halaman tambah Kontak
Future<void> _openFormCreate() async {
var result = await Navigator.push(
context, MaterialPageRoute(builder: (context) => FormKontak()));
if (result == 'save') {
await _getAllKontak();
}
}

//membuka halaman edit Kontak
Future<void> _openFormEdit(Kontak kontak) async {
var result = await Navigator.push(context,
MaterialPageRoute(builder: (context) => FormKontak(kontak: kontak)));
if (result == 'update') {
await _getAllKontak();
}
}
}



8. Selanjutnya buka file form_kontak.dart. Copy script di bawah ini dan paste. File ini akan kita gunakan sebagai form add dan edit sekaligus, jadi tidak perlu menggunakan dua file yang berbeda untuk membuat dua form yang sama.
    

// ignore_for_file: prefer_const_constructors_in_immutables, use_key_in_widget_constructors, prefer_const_constructors, non_constant_identifier_names

import 'package:flutter/material.dart';
import 'database/db_helper.dart';
import 'model/kontak.dart';


class FormKontak extends StatefulWidget {
final Kontak? kontak;

FormKontak({this.kontak});

@override
_FormKontakState createState() => _FormKontakState();
}

class _FormKontakState extends State<FormKontak> {
DbHelper db = DbHelper();

TextEditingController? name;
TextEditingController? lastName;
TextEditingController? mobileNo;
TextEditingController? email;
TextEditingController? company;

@override
void initState() {
name = TextEditingController(
text: widget.kontak == null ? '' : widget.kontak!.name);

mobileNo = TextEditingController(
text: widget.kontak == null ? '' : widget.kontak!.mobileNo);

email = TextEditingController(
text: widget.kontak == null ? '' : widget.kontak!.email);

company = TextEditingController(
text: widget.kontak == null ? '' : widget.kontak!.company);

super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Kontak'),
),
body: ListView(
padding: EdgeInsets.all(16.0),
children: [
Padding(
padding: const EdgeInsets.only(
top: 20,
),
child: TextField(
controller: name,
decoration: InputDecoration(
labelText: 'Name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
)),
),
),
Padding(
padding: const EdgeInsets.only(
top: 20,
),
child: TextField(
controller: mobileNo,
decoration: InputDecoration(
labelText: 'Mobile No',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
)),
),
),
Padding(
padding: const EdgeInsets.only(
top: 20,
),
child: TextField(
controller: email,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
)),
),
),
Padding(
padding: const EdgeInsets.only(
top: 20,
),
child: TextField(
controller: company,
decoration: InputDecoration(
labelText: 'Company',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
)),
),
),
Padding(
padding: const EdgeInsets.only(
top: 20
),
child: ElevatedButton(
child: (widget.kontak == null)
? Text(
'Add',
style: TextStyle(color: Colors.white),
)
: Text(
'Update',
style: TextStyle(color: Colors.white),
),
onPressed: () {
upsertKontak();
},
),
)
],
),
);
}

Future<void> upsertKontak() async {
if (widget.kontak != null) {
//update
await db.updateKontak(Kontak.fromMap({
'id' : widget.kontak!.id,
'name' : name!.text,
'mobileNo' : mobileNo!.text,
'email' : email!.text,
'company' : company!.text
}));
Navigator.pop(context, 'update');
} else {
//insert
await db.saveKontak(Kontak(
name: name!.text,
mobileNo: mobileNo!.text,
email: email!.text,
company: company!.text,
));
Navigator.pop(context, 'save');
}
}
}


9. Sampai disini semua tahap sudah selesai kita kerjakan. Tinggal saatnya kita melakukan uji coba. Silahkan nyalakan emulator kalian dan running app ini. Jika berhasil maka tampilannya akan terlihat seperti gambar di bawah ini.

Cara Membuat CRUD Flutter
Tampilan Akhir




Bagi yang merasa kesulitan mengikuti tutorial kali ini bisa mengunduh projectnya melalui github saya di link berikut ini https://github.com/nabilchen96/flutter_contact

Ok mantap sekali teman-teman!. Sekarang kalian sudah bisa menggunakan database untuk keperluan penyimapanan, menampilkan, peng-updatetan, dan penghapusan data. Saat ini kalian sudah bisa membuat berbagai macam aplikasi. Seperti note keeper, aplikasi pencatatan keuangan, dll.

Ok sekitan tutorial saya kali ini tentang cara membuat aplikasi crud dengan flutter dan sqflite, studi kasus aplikasi kontak. Semoga bermanfaat. Jika ada kesulitan silahkan tanyakan di kolom komentar atau bertanya langsung melalui fanspage tulisan saya. Sekian dan terima kasih :)

Post a Comment

Lebih baru Lebih lama