Flutter Tutorial
Flutter Tutorial
Saya
Machine Translated by Google
Tentang Tutorial
Flutter adalah framework open source untuk membuat aplikasi seluler berkualitas tinggi dan berperforma tinggi di
seluruh sistem operasi seluler - Android dan iOS. Ini menyediakan SDK yang sederhana, kuat, efisien, dan mudah
dipahami untuk menulis aplikasi seluler dalam bahasa Google sendiri, Dart.
Tutorial ini membahas dasar-dasar framework Flutter, pemasangan Flutter SDK, menyiapkan Android Studio untuk
mengembangkan aplikasi berbasis Flutter, arsitektur framework Flutter, dan mengembangkan semua jenis aplikasi
seluler menggunakan framework Flutter.
Hadirin
Tutorial ini disiapkan untuk para profesional yang bercita-cita untuk berkarier di bidang aplikasi seluler. Tutorial ini
dimaksudkan untuk membuat Anda nyaman dalam memulai framework Flutter dan berbagai fungsinya.
Prasyarat
Tutorial ini ditulis dengan asumsi bahwa pembaca sudah mengetahui apa itu Framework dan bahwa pembaca
memiliki pengetahuan yang baik tentang Pemrograman Berorientasi Objek dan pengetahuan dasar tentang
kerangka kerja Android dan pemrograman Dart.
Jika Anda seorang pemula dalam salah satu konsep ini, kami menyarankan Anda untuk membaca tutorial yang
terkait dengan ini terlebih dahulu, sebelum memulai dengan Flutter.
Semua konten dan grafik yang diterbitkan dalam e-book ini adalah milik Tutorials Point (I)
Prajurit Ltd. Pengguna e-book ini dilarang untuk menggunakan kembali, mempertahankan, menyalin,
mendistribusikan atau menerbitkan kembali isi atau bagian dari isi e-book ini dengan cara apapun tanpa persetujuan
tertulis dari penerbit.
Kami berusaha untuk memperbarui konten situs web dan tutorial kami tepat waktu dan setepat mungkin, namun
kontennya mungkin mengandung ketidakakuratan atau kesalahan. Tutorial Point (I) Pvt.
Ltd. tidak memberikan jaminan mengenai keakuratan, ketepatan waktu, atau kelengkapan situs web
kami atau kontennya termasuk tutorial ini. Jika Anda menemukan kesalahan di situs web kami atau
dalam tutorial ini, beri tahu kami di [email protected]
Saya
Machine Translated by Google
Berdebar
Daftar isi
Tentang Tutorial ............................................................... ............................................................... ...........................................Saya
ii
Machine Translated by Google
Berdebar
Berdebar
iv
Machine Translated by Google
1. Flutter – Pendahuluan
Secara umum, mengembangkan aplikasi seluler adalah tugas yang kompleks dan menantang. Ada banyak kerangka kerja
yang tersedia untuk mengembangkan aplikasi seluler. Android menyediakan kerangka kerja asli berdasarkan bahasa Java
dan iOS menyediakan kerangka kerja asli berdasarkan bahasa Objective-C / Shift.
Namun, untuk mengembangkan aplikasi yang mendukung kedua OS tersebut, kita perlu membuat kode dalam dua bahasa
berbeda menggunakan dua kerangka kerja berbeda. Untuk membantu mengatasi kerumitan ini, terdapat kerangka kerja
seluler yang mendukung kedua OS. Kerangka kerja ini berkisar dari kerangka kerja aplikasi seluler hybrid berbasis HTML
sederhana (yang menggunakan HTML untuk Antarmuka Pengguna dan JavaScript untuk logika aplikasi) hingga kerangka
kerja khusus bahasa kompleks (yang melakukan tugas berat untuk mengubah kode menjadi kode asli). Terlepas dari
kesederhanaan atau kerumitannya, kerangka kerja ini selalu memiliki banyak kelemahan, salah satu kelemahan utamanya
adalah kinerjanya yang lambat.
Dalam skenario ini, Flutter – kerangka kerja sederhana dan berperforma tinggi berdasarkan bahasa Dart, memberikan
kinerja tinggi dengan merender UI secara langsung di kanvas sistem operasi, bukan melalui kerangka kerja asli.
Flutter juga menawarkan banyak widget siap pakai (UI) untuk membuat aplikasi modern. Widget ini dioptimalkan untuk
lingkungan seluler dan mendesain aplikasi menggunakan widget semudah mendesain HTML.
Untuk lebih spesifik, aplikasi Flutter itu sendiri adalah sebuah widget. Widget Flutter juga mendukung animasi dan gerakan.
Logika aplikasi didasarkan pada pemrograman reaktif. Widget secara opsional dapat memiliki status. Dengan mengubah
status widget, Flutter akan secara otomatis (pemrograman reaktif) membandingkan status widget (lama dan baru) dan
merender widget hanya dengan perubahan yang diperlukan alih-alih merender ulang seluruh widget.
Fitur Flutter
Framework Flutter menawarkan fitur berikut kepada developer:
1
Machine Translated by Google
Berdebar
Keuntungan Flutter
Flutter hadir dengan widget cantik dan dapat disesuaikan untuk kinerja tinggi dan aplikasi seluler yang luar
biasa. Itu memenuhi semua kebutuhan dan persyaratan khusus. Selain itu, Flutter menawarkan lebih banyak
keuntungan seperti yang disebutkan di bawah ini:
• Dart memiliki repositori paket perangkat lunak yang besar yang memungkinkan Anda memperluas
kemampuan aplikasi Anda.
• Pengembang hanya perlu menulis satu basis kode untuk kedua aplikasi (platform Android dan iOS). Flutter
mungkin akan diperluas ke platform lain juga di masa mendatang.
• Flutter membutuhkan pengujian yang lebih rendah. Karena basis kode tunggalnya, cukup jika kita menulis
pengujian otomatis sekali untuk kedua platform.
• Kesederhanaan Flutter menjadikannya kandidat yang bagus untuk pengembangan cepat. Kemampuan
kustomisasi dan ekstensibilitas membuatnya semakin bertenaga.
• Dengan Flutter, developer memiliki kontrol penuh atas widget dan tata letaknya.
• Flutter menawarkan alat pengembang yang hebat, dengan hot reload yang luar biasa.
• Karena dikodekan dalam bahasa Dart, pengembang perlu mempelajari bahasa baru (meskipun mudah
dipelajari).
• Framework modern mencoba memisahkan logika dan UI sebanyak mungkin, tetapi di Flutter, antarmuka
pengguna dan logika saling bercampur. Kita bisa mengatasinya dengan menggunakan smart coding dan
menggunakan modul tingkat tinggi untuk memisahkan user interface dan logika.
• Flutter adalah framework lain untuk membuat aplikasi seluler. Pengembang mengalami kesulitan dalam
memilih alat pengembangan yang tepat di segmen yang padat penduduk.
2
Machine Translated by Google
Bab ini akan memandu Anda melalui penginstalan Flutter di komputer lokal Anda secara mendetail.
Instalasi di Windows
Di bagian ini, mari kita lihat cara menginstal Flutter SDK dan persyaratannya di sistem windows.
Langkah 1: Buka URL, https://flutter.dev/docs/get-started/install/windows dan unduh Flutter SDK terbaru. Pada April 2019,
versinya adalah 1.2.1 dan filenya adalah flutter_windows_v1.2.1-stable.zip.
Langkah 4: Flutter menyediakan alat, dokter flutter untuk memeriksa apakah semua persyaratan pengembangan flutter
telah terpenuhi.
dokter berdebar
Langkah 5: Menjalankan perintah di atas akan menganalisis sistem dan menampilkan laporannya seperti yang
ditunjukkan di bawah ini:
Ringkasan dokter (untuk melihat semua detail, jalankan flutter doctor -v): [ÿ] Flutter
(Channel stable, v1.2.1, di Microsoft Windows [Versi 10.0.17134.706], locale en-US) [ÿ] Android
toolchain - kembangkan untuk Perangkat Android (Android SDK versi 28.0.3) [ÿ] Android Studio
(versi 3.2) [ÿ] VS Code, edisi 64-bit (versi 1.29.1)
Laporan itu mengatakan bahwa semua alat pengembangan tersedia tetapi perangkat tidak terhubung.
Kami dapat memperbaikinya dengan menghubungkan perangkat android melalui USB atau memulai emulator
android.
Langkah 6: Instal SDK Android terbaru, jika dilaporkan oleh dokter bergetar
Langkah 7: Instal Android Studio terbaru, jika dilaporkan oleh dokter bergetar
Langkah 8: Mulai emulator android atau sambungkan perangkat android asli ke sistem.
Langkah 9: Instal plugin Flutter dan Dart untuk Android Studio. Ini menyediakan template startup untuk membuat aplikasi
Flutter baru, opsi untuk menjalankan dan men-debug aplikasi Flutter di studio Android itu sendiri, dll.,
3
Machine Translated by Google
Berdebar
Instalasi di MacOS
Untuk menginstal Flutter di MacOS, Anda harus mengikuti langkah-langkah berikut:
Langkah 3: Perbarui jalur sistem untuk menyertakan direktori flutter bin (dalam file ~/.bashrc).
Langkah 4: Aktifkan jalur yang diperbarui di sesi saat ini menggunakan perintah di bawah ini dan kemudian
verifikasi juga.
sumber ~/.bashrc
sumber $HOME/.bash_profile
echo $PATH
Flutter menyediakan alat, dokter flutter untuk memeriksa apakah semua persyaratan pengembangan flutter
terpenuhi. Ini mirip dengan mitra Windows.
Langkah 6: Instal SDK Android terbaru, jika dilaporkan oleh dokter bergetar
Langkah 7: Instal Android Studio terbaru, jika dilaporkan oleh dokter bergetar
Langkah 8: Mulai emulator android atau sambungkan perangkat android asli ke sistem untuk mengembangkan
aplikasi android.
Langkah 9: Buka simulator iOS atau sambungkan perangkat iPhone asli ke sistem untuk mengembangkan
aplikasi iOS.
Langkah 10: Instal plugin Flutter dan Dart untuk Android Studio. Ini menyediakan template startup untuk
membuat aplikasi Flutter baru, opsi untuk menjalankan dan men-debug aplikasi Flutter di studio Android itu
sendiri, dll.,
4
Machine Translated by Google
di Android Studio
Pada bab ini, mari kita membuat aplikasi Flutter sederhana untuk memahami dasar-dasar pembuatan
aplikasi flutter di Android Studio.
Langkah 2: Buat Proyek Flutter. Untuk ini, klik File -> New -> New Flutter Project
5
Machine Translated by Google
Berdebar
Langkah 3: Pilih Aplikasi Flutter. Untuk ini, pilih Flutter Application dan klik Next.
6
Machine Translated by Google
Berdebar
Android Studio membuat aplikasi flutter yang berfungsi penuh dengan fungsionalitas minimal.
Mari kita periksa struktur aplikasi dan kemudian ubah kode untuk melakukan tugas kita.
7
Machine Translated by Google
Berdebar
• android - Kode sumber yang dihasilkan secara otomatis untuk membuat aplikasi android
• ios - Kode sumber yang dihasilkan secara otomatis untuk membuat aplikasi ios
• lib - Folder utama yang berisi kode Dart yang ditulis menggunakan framework flutter
• test - Folder yang berisi kode Dart untuk menguji aplikasi flutter
8
Machine Translated by Google
Berdebar
Langkah 7: Ganti kode dart di file lib/ main.dart dengan kode di bawah ini:
import 'package:flutter/material.dart';
kembalikan MaterialApp(
title: 'Hello World Demo Application', theme:
ThemeData( primarySwatch: Colors.blue, ), home:
MyHomePage(title: 'Home page'), );
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
Text( 'Hello World',
), );
}
}
• Baris 1: mengimpor paket flutter, material. Materinya adalah paket flutter untuk membuat
antarmuka pengguna sesuai dengan pedoman desain Material yang ditentukan oleh Android .
• Baris 3: Ini adalah titik masuk aplikasi Flutter. Memanggil fungsi runApp dan meneruskannya
sebagai objek kelas MyApp . Tujuan dari fungsi runApp adalah untuk melampirkan widget
yang diberikan ke layar.
• Baris 5 - 17: Widget digunakan untuk membuat UI dalam framework flutter. StatelessWidget
adalah widget, yang tidak mempertahankan status widget apa pun. MyApp memperluas
StatelessWidget dan mengganti metode pembuatannya . Tujuan dibangunnya
9
Machine Translated by Google
Berdebar
Metodenya adalah membuat bagian dari UI aplikasi. Di sini, metode build menggunakan
MaterialApp, sebuah widget untuk membuat UI level root dari aplikasi. Ini memiliki tiga
properti - judul, tema , dan rumah.
o tema adalah tema widget. Di sini, kami menetapkan warna biru sebagai warna
keseluruhan aplikasi menggunakan kelas ThemeData dan propertinya, primarySwatch.
o rumah adalah UI bagian dalam aplikasi, yang kami atur widget lain,
Halaman Beranda Saya
10
Machine Translated by Google
Berdebar
11
Machine Translated by Google
Widget
Konsep inti framework Flutter adalah Di Flutter, Semuanya adalah widget. Widget pada dasarnya
adalah komponen antarmuka pengguna yang digunakan untuk membuat antarmuka pengguna aplikasi.
Di Flutter, aplikasi itu sendiri adalah sebuah widget. Aplikasi ini adalah widget tingkat atas dan UI-nya
dibangun menggunakan satu atau lebih turunan (widget), yang dibangun lagi menggunakan widget
turunannya. Fitur komposisi ini membantu kami membuat antarmuka pengguna dengan kerumitan apa pun.
Misalnya, hirarki widget dari aplikasi hello world (dibuat di bab sebelumnya) seperti yang ditentukan
dalam diagram berikut:
12
Machine Translated by Google
Berdebar
• MyApp adalah widget yang dibuat pengguna dan dibuat menggunakan widget asli Flutter,
Aplikasi Bahan.
• MaterialApp memiliki properti rumah untuk menentukan antarmuka pengguna halaman beranda,
yang lagi-lagi merupakan widget buatan pengguna, MyHomePage.
• body digunakan untuk menentukan antarmuka pengguna utamanya dan appBar digunakan untuk menentukan headernya
antarmuka pengguna.
• Header UI dibuat menggunakan widget asli flutter, AppBar dan Body UI dibuat menggunakan
Widget tengah .
• Widget Tengah memiliki properti, Anak, yang mengacu pada konten aktual dan dibangun menggunakan widget Teks .
Gerakan
Konsep Negara
Widget Flutter mendukung pemeliharaan State dengan menyediakan widget khusus, StatefulWidget.
Widget harus diturunkan dari widget StatefulWidget untuk mendukung pemeliharaan status dan semua widget lainnya
harus diturunkan dari StatelessWidget. Widget Flutter bersifat reaktif secara native. Ini mirip dengan reactjs dan
StatefulWidget akan dirender secara otomatis setiap kali keadaan internalnya diubah. Perenderan ulang dioptimalkan
dengan menemukan perbedaan antara UI widget lama dan baru dan hanya merender perubahan yang diperlukan.
Lapisan
Konsep paling penting dari framework Flutter adalah bahwa framework dikelompokkan ke dalam beberapa kategori dalam
hal kompleksitas dan disusun dengan jelas dalam lapisan-lapisan dengan kompleksitas yang menurun. Lapisan dibangun
menggunakan lapisan tingkat berikutnya langsung. Lapisan paling atas adalah widget khusus untuk Android dan iOS.
Lapisan berikutnya memiliki semua widget asli bergetar. Lapisan berikutnya adalah lapisan Rendering , yang merupakan
komponen perender tingkat rendah dan merender semua yang ada di aplikasi flutter. Lapisan turun ke kode khusus
platform inti.
13
Machine Translated by Google
Berdebar
• Fitur interaktif dapat digabungkan kapan pun diperlukan menggunakan widget GestureDetector .
• Flutter menawarkan desain berlapis sehingga setiap lapisan dapat diprogram tergantung pada
kerumitan tugas.
Kami akan membahas semua konsep ini secara rinci di bab-bab mendatang.
14
Machine Translated by Google
Dart adalah bahasa pemrograman tujuan umum sumber terbuka. Ini awalnya dikembangkan oleh
Google. Dart adalah bahasa berorientasi objek dengan sintaks C-style. Ini mendukung konsep
pemrograman seperti antarmuka, kelas, tidak seperti bahasa pemrograman lain Dart tidak mendukung
array. Koleksi Dart dapat digunakan untuk mereplikasi struktur data seperti array, generik, dan
pengetikan opsional.
batal main() {
Dart menggunakan kata kunci var untuk mendeklarasikan variabel. Sintaks var didefinisikan di bawah ini,
Kata kunci final dan const digunakan untuk mendeklarasikan konstanta. Mereka didefinisikan sebagai berikut:
batal main()
{ final a = 12;
const pi = 3,14;
cetak(a); cetak(pi);
• String: Ini mewakili urutan karakter. Nilai string ditentukan dalam tanda kutip tunggal atau ganda.
• Boolean: Dart menggunakan kata kunci bool untuk mewakili nilai Boolean – benar dan salah.
• Daftar dan Peta: Ini digunakan untuk mewakili kumpulan objek. Daftar sederhana dapat
didefinisikan sebagai berikut:
batal main()
{ var daftar = [1,2,3,4,5];
cetak(daftar);
}
15
Machine Translated by Google
Berdebar
• Dinamis: Jika tipe variabel tidak ditentukan, maka tipe defaultnya adalah dinamis. Itu
contoh berikut mengilustrasikan variabel tipe dinamis:
void main()
{ nama dinamis = "Dart";
cetak(nama);
}
Loop digunakan untuk mengulang blok kode sampai kondisi tertentu terpenuhi. Dart mendukung untuk,
untuk..di , while dan do.. while loop.
Mari kita pahami contoh sederhana tentang penggunaan pernyataan kontrol dan loop:
void main()
{ for( var i = 1 ; i <= 10; i++ ) { if(i%2==0) {
cetak(i);
}
}
}
Fungsi
Fungsi adalah sekelompok pernyataan yang bersama-sama melakukan tugas tertentu. Mari kita lihat fungsi
sederhana di Dart seperti yang ditunjukkan di sini:
batal main()
{ tambah(3,4);
}
16
Machine Translated by Google
Berdebar
Kelas adalah cetak biru untuk membuat objek. Definisi kelas mencakup hal-hal berikut:
• Bidang
• Konstruktor
• Fungsi
kelas Karyawan {
nama string;
// metode pengambil
String dapatkan emp_name
{ nama kembali;
}
cetak(nama);
}
} void main() { //
pembuatan objek
Karyawan emp = Karyawan baru();
emp.name="karyawan1"; emp.hasil(); //
pemanggilan fungsi
}
17
Machine Translated by Google
Seperti yang kita pelajari di bab sebelumnya, widget adalah segalanya dalam framework Flutter. Kami telah
mempelajari cara membuat widget baru di bab sebelumnya.
Di bab ini, mari kita pahami konsep sebenarnya di balik pembuatan widget dan berbagai jenis widget yang
tersedia di framework Flutter .
Mari kita periksa widget MyHomePage aplikasi Hello World . Kode untuk tujuan ini adalah seperti yang
diberikan di bawah ini:
@mengesampingkan
);
}
}
Perhatikan bahwa StatelessWidget hanya membutuhkan satu metode build untuk diterapkan di kelas
turunannya. Metode build mendapatkan lingkungan konteks yang diperlukan untuk membuat widget melalui
parameter BuildContext dan mengembalikan widget yang dibuatnya.
Dalam kode, kami telah menggunakan title sebagai salah satu argumen konstruktor dan juga menggunakan
Key sebagai argumen lainnya. Judul digunakan untuk menampilkan judul dan Kunci digunakan untuk
mengidentifikasi widget di lingkungan build .
Di sini, metode build memanggil metode build Scaffold, yang selanjutnya memanggil metode build AppBar
dan Center untuk membangun antarmuka penggunanya.
18
Machine Translated by Google
Berdebar
Untuk pemahaman yang lebih baik, representasi visual yang sama diberikan di bawah ini:
Widget khusus Android dirancang sesuai dengan panduan desain Material oleh OS Android. Widget khusus Android disebut
sebagai widget Material.
Widget khusus iOS dirancang sesuai dengan Pedoman Antarmuka Manusia oleh Apple dan disebut sebagai widget
Cupertino .
Beberapa widget material yang paling banyak digunakan adalah sebagai berikut:
• Perancah
AppBar
19
Machine Translated by Google
Berdebar
• TabBarView
• ListTile
• Tombol Angkat
• Tombol Ikon
• Tombol Turun
• Tombol PopupMenu
• Bar Tombol
• Bidang Teks
• Kotak centang
• Radio
• Beralih
• Penggeser
• SimpleDialog •
AlertDialog
Beberapa widget Cupertino yang paling banyak digunakan adalah sebagai berikut:
• Tombol Cupertino
• Cupertino Picker
• CupertinoDatePicker •
CupertinoTimerPicker
• CupertinoNavigationBar
• CupertinoTabBar
• CupertinoTabScaffold •
CupertinoTabView •
CupertinoTextField
• Dialog Cupertino
• CupertinoFullscreenDialogTransition •
CupertinoPageScaffold
• CupertinoPageTransition
• CupertinoActivityIndicator •
CupertinoAlertDialog •
CupertinoPopupSurface
20
Machine Translated by Google
Berdebar
• Cupertino Slider
• Kontainer: Kotak persegi panjang yang dihias menggunakan widget BoxDecoration dengan
latar belakang, batas dan bayangan.
Kami akan memeriksa tata letak widget secara mendetail di bab Pengenalan widget tata letak yang akan datang .
Widget yang diturunkan dari StatelessWidget tidak memiliki informasi status apa pun tetapi mungkin berisi widget
yang diturunkan dari StatefulWidget. Sifat dinamis dari aplikasi adalah melalui perilaku interaktif widget dan
perubahan status selama interaksi. Misalnya, mengetuk tombol penghitung akan menambah/mengurangi status
internal penghitung sebanyak satu dan sifat reaktif widget Flutter akan merender ulang widget secara otomatis
menggunakan informasi status baru.
Kita akan mempelajari konsep widget StatefulWidget secara mendetail di bab manajemen Status yang akan
datang .
sejumlah besar widget dasar untuk membuat antarmuka pengguna yang sederhana dan kompleks dengan cara
independen platform. Mari kita lihat beberapa widget dasar di bab ini.
Teks
Widget teks digunakan untuk menampilkan seutas string. Gaya string dapat diatur dengan menggunakan properti
gaya dan kelas TextStyle . Contoh kode untuk tujuan ini adalah sebagai berikut:
Widget teks memiliki konstruktor khusus, Text.rich, yang menerima turunan dari tipe TextSpan untuk menentukan
string dengan gaya yang berbeda. Widget TextSpan bersifat rekursif dan menerima TextSpan sebagai turunannya.
Contoh kode untuk tujuan ini adalah sebagai berikut:
21
Machine Translated by Google
Berdebar
• textAlign, TextAlign: Perataan teks seperti kanan, kiri, ratakan, dll, menggunakan
kelas TextAlign
• textDirection, TextDirection: Arah teks mengalir, baik dari kiri ke kanan atau kanan
ke kiri
Gambar
Widget gambar digunakan untuk menampilkan gambar dalam aplikasi. Widget gambar menyediakan berbagai
konstruktor untuk memuat gambar dari berbagai sumber dan mereka adalah sebagai berikut:
Opsi termudah untuk memuat dan menampilkan gambar di Flutter adalah dengan menyertakan gambar sebagai
aset aplikasi dan memuatnya ke dalam widget sesuai permintaan.
• Buat folder, aset di folder proyek dan tempatkan gambar yang diperlukan.
berdebar:
aktiva:
- aset/smiley.png
Gambar.aset('aset/smiley.png')
22
Machine Translated by Google
Berdebar
• Kode sumber lengkap widget MyHomePage dari aplikasi hello world dan
hasilnya seperti gambar di bawah ini:
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title: Text(this.title), ),
body: Center( child: Image.asset("assets/
smiley.png")
), );
}
23
Machine Translated by Google
Berdebar
Ikon
Widget ikon digunakan untuk menampilkan mesin terbang dari font yang dijelaskan di kelas IconData . Kode untuk
memuat ikon email sederhana adalah sebagai berikut:
Ikon(Ikon.email)
Adapun source code lengkap untuk mengaplikasikannya pada aplikasi hello world adalah sebagai berikut:
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
Icon(Icons.email)
), );
}
}
24
Machine Translated by Google
Berdebar
25
Machine Translated by Google
Karena konsep inti Flutter adalah Semuanya adalah widget, Flutter menggabungkan fungsionalitas tata letak
antarmuka pengguna ke dalam widget itu sendiri. Flutter menyediakan cukup banyak widget yang didesain
khusus seperti Container, Center, Align, dll., hanya untuk tujuan tata letak antarmuka pengguna. Widget
yang dibuat dengan menyusun widget lain biasanya menggunakan widget tata letak. Mari kita pelajari konsep
tata letak Flutter di bab ini.
Jenis LayoutWidget
Widget tata letak dapat dikelompokkan menjadi dua kategori berbeda berdasarkan anaknya:
Mari kita pelajari kedua jenis widget dan fungsinya di bagian yang akan datang.
Misalnya, widget Tengah hanya memusatkan widget anak-anak sehubungan dengan widget induknya dan
widget Kontainer memberikan fleksibilitas penuh untuk menempatkannya di tempat tertentu di dalamnya
menggunakan opsi berbeda seperti padding, dekorasi, dll.,
Widget anak tunggal adalah opsi bagus untuk membuat widget berkualitas tinggi yang memiliki fungsi tunggal
seperti tombol, label, dll.,
Kode untuk membuat tombol sederhana menggunakan widget Container adalah sebagai berikut:
@ganti
Widget build(BuildContext context) { return
Container( decoration: const
BoxDecoration( border: Border( top:
BorderSide(width: 1.0, color:
Color(0xFFFFFFFFFF)), kiri: BorderSide(width: 1.0, color:
Color(0xFFFFFFFFFF) )), kanan: BorderSide(width: 1.0, color:
Color(0xFFFF000000)), bawah: BorderSide(width: 1.0, color:
Color(0xFFFF000000)), ), ), child: Container(
26
Machine Translated by Google
Berdebar
Warna.hitam)), ), );
}
}
Di sini, kami telah menggunakan dua widget – widget Wadah dan widget Teks . Hasil dari widget adalah
sebagai tombol kustom seperti yang ditunjukkan di bawah ini:
Mari kita periksa beberapa widget tata letak anak tunggal terpenting yang disediakan oleh Flutter:
• Padding: Digunakan untuk mengatur widget turunannya dengan padding yang diberikan. Di sini, padding
dapat disediakan oleh kelas EdgeInsets .
• Align: Sejajarkan widget turunannya dengan sendirinya menggunakan nilai properti perataan . Nilai untuk
properti penyelarasan dapat diberikan oleh kelas FractionalOffset . Kelas FractionalOffset menentukan
offset dalam hal jarak dari kiri atas.
Tengah( anak:
Kontainer( tinggi:
100.0, lebar: 100.0,
warna: Warna.kuning,
anak: Ratakan( penjajaran:
FractionalOffset(0.2, 0.6), anak: Kontainer( tinggi:
40.0, lebar: 40.0, warna: Warna.merah , ), ), ), ),
• FittedBox: Menskalakan widget anak dan kemudian memposisikannya sesuai dengan kecocokan yang
ditentukan.
• AspectRatio: Ini mencoba mengubah ukuran widget anak ke rasio aspek yang ditentukan
27
Machine Translated by Google
Berdebar
• ConstrainedBox
• Garis dasar
• Tinggi Intrinsik
• Lebar Intrinsik
• GluedBox
• Di Luar Panggung
• OverflowBox
• Ukuran Kotak
• SizedOverflowBox
• Transformasi
• CustomSingleChildLayout
Aplikasi hello world kami menggunakan widget tata letak berbasis bahan untuk mendesain halaman beranda. Mari
kita modifikasi aplikasi hello world kita untuk membangun halaman beranda menggunakan widget tata letak dasar
seperti yang ditentukan di bawah ini:
• Kontainer: Generik, anak tunggal, widget kontainer berbasis kotak dengan perataan, padding, batas, dan
margin bersama dengan fitur gaya yang kaya.
• Tengah: Sederhana, widget penampung anak tunggal, yang memusatkan widget anaknya.
Kode yang dimodifikasi dari widget MyHomePage dan MyApp adalah sebagai berikut:
@mengesampingkan
@mengesampingkan
kembalikan Wadah(
dekorasi: KotakDekorasi(
28
Machine Translated by Google
Berdebar
warna: Warna.putih,
),
padding: EdgeInsets.all(25),
anak: Tengah(anak:
Teks(
'Halo Dunia',
),
textDirection: TextDirection.ltr,
),
));
}
Di Sini,
• Widget wadah adalah widget tingkat atas atau root. Kontainer dikonfigurasi menggunakan properti dekorasi
dan padding untuk mengatur tata letak kontennya.
• BoxDecoration memiliki banyak properti seperti color, border, dll., untuk menghias widget Container dan
disini, color digunakan untuk mengatur warna container.
• padding widget Container diatur dengan menggunakan kelas dgeInsets , yang menyediakan opsi untuk
menentukan nilai padding.
• Center adalah widget turunan dari widget Container . Sekali lagi, Teks adalah turunan dari widget Tengah .
Teks digunakan untuk menampilkan pesan dan Pusat digunakan untuk memusatkan pesan teks
sehubungan dengan widget induk, Wadah.
29
Machine Translated by Google
Berdebar
Hasil akhir dari kode yang diberikan di atas adalah contoh tata letak seperti yang ditunjukkan di bawah ini:
Misalnya, widget Baris memungkinkan peletakan turunannya dalam arah horizontal, sedangkan widget Kolom memungkinkan
peletakan turunannya dalam arah vertikal. Dengan menyusun Baris dan Kolom, widget dengan tingkat kerumitan apa pun dapat
dibangun.
Mari kita pelajari beberapa widget yang sering digunakan di bagian ini.
• Diperluas - Digunakan untuk membuat anak-anak dari widget Baris dan Kolom untuk menempati
luas maksimum yang memungkinkan.
30
Machine Translated by Google
Berdebar
import 'package:flutter/material.dart';
}
}
@mengesampingkan
Teks(
'Halo Dunia', )),
);
}
}
31
Machine Translated by Google
Berdebar
• Di Sini,
• Kami telah membuat widget MyHomePage dengan memperluas StatelessWidget alih-alih StatefulWidget default
dan kemudian menghapus kode yang relevan.
• Sekarang, buat widget baru, ProductBox sesuai dengan desain yang ditentukan seperti yang ditunjukkan
di bawah:
Teks(ini.deskripsi), Teks("Harga:
" + ini.harga.toString()), ], )))
]))); }
}
32
Machine Translated by Google
Berdebar
• ProductBox telah menggunakan empat argumen seperti yang ditentukan di bawah ini:
• ProductBox menggunakan tujuh widget bawaan seperti yang ditentukan di bawah ini:
o Kontainer
o Diperluas
o Baris
o Kolom
o Kartu
o Teks
o Gambar
33
Machine Translated by Google
Berdebar
• ProductBox dirancang menggunakan widget yang disebutkan di atas. Susunan atau hierarki widget
ditentukan dalam diagram yang ditunjukkan di bawah ini:
• Sekarang, tempatkan beberapa gambar tiruan (lihat di bawah) untuk informasi produk di folder aset aplikasi
dan konfigurasikan folder aset di file pubspec.yaml seperti yang ditunjukkan di bawah ini:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/
pendrive.png - aset/appimages/pixel.png -
aset/appimages/tablet.png
iPhone.png
34
Machine Translated by Google
Berdebar
Piksel.png
Laptop.png
Tablet.png
Flashdisk.png
Floppy.png
• Terakhir, Gunakan widget ProductBox di widget MyHomePage seperti yang ditentukan di bawah ini:
@mengesampingkan
35
Machine Translated by Google
Berdebar
ProductBox( nama:
"Pixel", deskripsi: "Pixel adalah ponsel paling berfitur yang pernah ada",
harga: 800, gambar: "pixel.png"), ProductBox( nama: "Laptop", deskripsi:
"Laptop adalah alat pengembangan paling produktif ", harga: 2000, gambar:
"laptop.png"),
ProductBox( nama:
"Tablet", deskripsi: "Tablet adalah perangkat paling berguna yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama:
"Flashdisk", deskripsi: "Flashdisk adalah media penyimpanan yang
berguna", harga: 100, gambar: "flashdisk.png"), ProductBox(
], ));
}
}
import 'package:flutter/material.dart';
kembalikan
MaterialApp( judul: 'Flutter
Demo', tema:
ThemeData( primarySwatch: Warna.biru,
36
Machine Translated by Google
Berdebar
),
beranda: MyHomePage(judul: 'Halaman beranda demo tata letak produk'), );
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Listing")), body: ListView( shrinkWrap: true, padding: const
EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0) , anak-anak:
<Widget>[ ProductBox( nama: "iPhone", deskripsi: "iPhone
adalah ponsel stylist yang pernah ada", harga: 1000, gambar: "iphone.png"),
ProductBox( nama:
"Pixel", deskripsi: "Pixel adalah ponsel paling berfitur yang pernah ada",
harga: 800, gambar: "pixel.png"), ProductBox( nama: "Laptop", deskripsi:
"Laptop adalah alat pengembangan paling produktif ", harga: 2000,
gambar: "laptop.png"),
ProductBox( nama:
"Tablet", deskripsi: "Tablet adalah perangkat paling berguna yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama:
"Flashdisk", deskripsi: "Flashdisk adalah media penyimpanan
yang berguna", harga: 100, gambar: "flashdisk.png"), ProductBox(
], ));
}
}
37
Machine Translated by Google
Berdebar
FontWeight.bold)),
Teks(ini.deskripsi),
Teks("Harga: " + ini.harga.toString()), ], )))
])));
}
}
38
Machine Translated by Google
Berdebar
39
Machine Translated by Google
Gerakan pada dasarnya adalah cara bagi pengguna untuk berinteraksi dengan aplikasi seluler (atau
perangkat berbasis sentuhan apa pun). Gestur secara umum didefinisikan sebagai tindakan / gerakan
fisik apa pun dari pengguna dengan maksud untuk mengaktifkan kontrol tertentu pada perangkat seluler.
Gestur sesederhana mengetuk layar perangkat seluler hingga tindakan yang lebih kompleks yang
digunakan dalam aplikasi game.
• Ketuk: Menyentuh permukaan perangkat dengan ujung jari untuk waktu yang singkat dan kemudian
melepaskan ujung jari.
• Seret: Menyentuh permukaan perangkat dengan ujung jari lalu menggerakkan ujung jari dengan
mantap dan terakhir melepaskan ujung jari.
• Flick: Mirip dengan menyeret, tetapi melakukannya dengan cara yang lebih cepat.
• Panning: Menyentuh permukaan perangkat dengan ujung jari dan menggerakkannya ke segala
arah tanpa melepaskan ujung jari.
Flutter memberikan dukungan luar biasa untuk semua jenis gestur melalui widget eksklusifnya,
GestureDetector. GestureDetector adalah widget non-visual yang terutama digunakan untuk mendeteksi
gerakan pengguna. Untuk mengidentifikasi isyarat yang ditargetkan pada widget, widget dapat
ditempatkan di dalam widget GestureDetector. GestureDetector akan menangkap gestur dan mengirim
beberapa peristiwa berdasarkan gestur tersebut.
• Ketuk
o onTapDown
o onTapUp
o onTap
o onTapCancel
o onDoubleTap
• Tekan lama
o onLongPress
40
Machine Translated by Google
Berdebar
• Tarik vertikal
o diVerticalDragStart
o onVerticalDragUpdate
o diVerticalDragEnd
• Tarik horizontal
o pada HorizontalDragStart
o pada HorizontalDragUpdate
o pada HorizontalDragEnd
• Pan
o onPanStart
o onPanUpdate
o onPanEnd
Sekarang, mari kita modifikasi aplikasi hello world untuk menyertakan fitur deteksi gerakan dan mencoba
memahami konsepnya.
• Ubah konten body widget MyHomePage seperti yang ditunjukkan di bawah ini:
body:
Center( anak:
GestureDetector( onTap:
() { _showDialog(konteks);
},
anak: Teks(
'Halo Dunia',
)
)
),
• Perhatikan bahwa di sini kita telah menempatkan widget GestureDetector di atas Teks
widget dalam hierarki widget, menangkap peristiwa onTap dan akhirnya menampilkan jendela
dialog.
• Terapkan fungsi *_showDialog* untuk menampilkan dialog saat pengguna mem-tab pesan halo dunia .
Ini menggunakan widget showDialog dan AlertDialog generik untuk membuat widget dialog baru.
Kode ditunjukkan di bawah ini:
41
Machine Translated by Google
Berdebar
kembalikan
AlertDialog( judul: Teks
baru("Pesan"), konten: Teks baru("Halo
Dunia"), tindakan: <Widget>[ Tombol
Datar baru( anak: Teks baru("Tutup"),
onPressed: () { Navigator.
dari(konteks).pop(); }, ), ], ); }, ); }
• Aplikasi akan dimuat ulang di perangkat menggunakan fitur Hot Reload . Sekarang, cukup klik pesan,
Halo Dunia dan itu akan menampilkan dialog seperti di bawah ini:
42
Machine Translated by Google
Berdebar
import 'package:flutter/material.dart';
kembalikan MaterialApp(
title: 'Hello World Demo Application', theme:
ThemeData( primarySwatch: Colors.blue, ), home:
MyHomePage(title: 'Home page'), );
}
}
Navigator.of(konteks).pop(); }, ), ], ); }, );
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title: Text(this.title), ),
43
Machine Translated by Google
Berdebar
body:
Center( anak:
GestureDetector( onTap:
() { _showDialog(konteks); },
anak: Teks(
);
}
}
Terakhir, Flutter juga menyediakan mekanisme deteksi gestur tingkat rendah melalui widget Listener . Ini
akan mendeteksi semua interaksi pengguna dan kemudian mengirimkan peristiwa berikut:
• PointerDownEvent
• PointerMoveEvent
• PointerUpEvent
• PointerCancelEvent
Flutter juga menyediakan sekumpulan kecil widget untuk melakukan gestur spesifik dan lanjutan.
Widget tercantum di bawah ini:
• AbsorbPointer: Menghentikan proses deteksi gerakan itu sendiri sehingga setiap widget yang tumpang
tindih juga tidak dapat berpartisipasi dalam proses deteksi gerakan dan karenanya, tidak ada
peristiwa yang dimunculkan.
44
Machine Translated by Google
Mengelola status dalam aplikasi adalah salah satu proses terpenting dan perlu dalam siklus hidup aplikasi.
• Setelah pengguna masuk, aplikasi harus mempertahankan semua detail pengguna yang masuk
layar.
• Sekali lagi, saat pengguna memilih produk dan menyimpannya ke keranjang, informasi keranjang harus tetap ada di
antara halaman sampai pengguna memeriksa keranjang.
• Pengguna dan informasi keranjang mereka setiap saat disebut keadaan aplikasi
pada saat itu.
Manajemen status dapat dibagi menjadi dua kategori berdasarkan durasi status tertentu berlangsung dalam aplikasi.
• Ephemeral - Berlangsung selama beberapa detik seperti keadaan animasi saat ini atau satu halaman seperti peringkat
produk saat ini. Flutter mendukungnya melalui StatefulWidget.
• status aplikasi - Terakhir untuk seluruh aplikasi seperti detail pengguna yang masuk, informasi keranjang,
dll., Flutter mendukungnya melalui scoped_model.
Mari kita buat widget, RatingBox dengan pemeliharaan negara. Tujuan dari widget ini adalah untuk menunjukkan peringkat
terkini dari produk tertentu. Proses langkah demi langkah untuk membuat widget RatingBox dengan pemeliharaan status
adalah sebagai berikut:
45
Machine Translated by Google
Berdebar
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton(
], );
}
46
Machine Translated by Google
Berdebar
Di sini, kami telah menggunakan tiga bintang, dibuat menggunakan widget IconButton dan mengaturnya
menggunakan widget Baris dalam satu baris. Idenya adalah untuk menunjukkan peringkat melalui urutan bintang merah.
Misalnya, jika peringkatnya adalah dua bintang, maka dua bintang pertama berwarna merah dan yang terakhir
berwarna putih.
batal _setRatingAsOne()
{ setState( () { _rating = 1; });
batal _setRatingAsTwo() {
setState( ()
{ _rating = 2; });
batal _setRatingAsThree()
{ setState( () { _rating = 3; });
• Di sini, setiap metode menetapkan peringkat widget saat ini melalui setState
• Sambungkan gerakan pengguna (mengetuk bintang) ke metode perubahan status yang tepat.
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton(
47
Machine Translated by Google
Berdebar
onPressed: _setRatingAsTwo,
iconSize: _size, ), ),
Container( padding: EdgeInsets.all(0),
anak: IconButton(
], );
}
Di sini, event onPressed memanggil fungsi yang relevan untuk mengubah status dan selanjutnya mengubah
antarmuka pengguna. Misalnya, jika pengguna mengklik bintang ketiga, maka _setRatingAsThree akan
dipanggil dan akan mengubah _rating menjadi 3. Karena status diubah, metode build akan dipanggil lagi dan
antarmuka pengguna akan dibuat dan dirender lagi.
batal _setRatingAsOne()
{ setState( () { _rating = 1; });
batal _setRatingAsTwo() {
setState( ()
{ _rating = 2; });
batal _setRatingAsThree()
{ setState( () { _rating = 3; });
48
Machine Translated by Google
Berdebar
ukuran_ganda = 20;
cetak(_peringkat);
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton(
], );
}
}
Mari kita buat aplikasi baru dan gunakan widget RatingBox yang baru kita buat untuk menunjukkan peringkat
produk.
import 'package:flutter/material.dart';
49
Machine Translated by Google
Berdebar
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
Teks(
'Halo Dunia', )),
);
}
}
• Di Sini,
• Kami telah membuat widget MyHomePage dengan memperluas StatelessWidget sebagai gantinya
default StatefulWidget dan kemudian menghapus kode yang relevan.
• Buat widget ProductBox untuk mencantumkan produk beserta peringkat seperti yang ditentukan di bawah ini:
50
Machine Translated by Google
Berdebar
MainAxisAlignment.spaceMerata,
anak-anak:
<Widget>[ Text(ini.nama,
gaya: TextStyle(fontWeight:
FontWeight.bold)),
Text(this.description),
Text("Harga: " + this.price.toString()), RatingBox(), ], )))
])));
}
}
• Perbarui widget MyHomePage untuk menyertakan widget ProductBox seperti yang ditentukan
di bawah:
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Listing")), body: ListView( shrinkWrap: true, padding: const
EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0) , anak-anak:
<Widget>[ ProductBox( nama: "iPhone", deskripsi: "iPhone
adalah ponsel stylist yang pernah ada", harga: 1000, gambar: "iphone.png"),
ProductBox( nama: "Pixel", deskripsi: " Pixel adalah ponsel paling berfitur
yang pernah ada", harga: 800, gambar: "pixel.png"), ProductBox( nama:
"Laptop", deskripsi: "Laptop adalah alat pengembangan paling
produktif",
51
Machine Translated by Google
Berdebar
harga: 2000,
gambar: "laptop.png"),
ProductBox( nama:
"Tablet", deskripsi: "Tablet adalah perangkat paling berguna yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama:
"Flashdisk", deskripsi: "Flashdisk adalah media penyimpanan
yang berguna", harga: 100, gambar: "flashdisk.png"),
Kotak Produk(
nama: "Floppy Drive",
deskripsi: "Floppy drive adalah penyimpanan penyelamat yang berguna
sedang",
harga: 20,
gambar: "floppy.png"),
], ));
}
}
import 'package:flutter/material.dart';
}
}
@mengesampingkan
52
Machine Translated by Google
Berdebar
shrinkWrap: true,
padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), anak-anak:
<Widget>[ ProductBox( nama: "iPhone", deskripsi: "iPhone adalah ponsel
stylist yang pernah ada", harga: 1000, gambar : "iphone.png"),
ProductBox( nama:
"Pixel", deskripsi: "Pixel adalah ponsel paling berfitur yang pernah ada",
harga: 800, gambar: "pixel.png"), ProductBox( nama: "Laptop", deskripsi:
"Laptop adalah alat pengembangan paling produktif ", harga: 2000,
gambar: "laptop.png"),
ProductBox( nama:
"Tablet", deskripsi: "Tablet adalah perangkat paling berguna yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama:
"Flashdisk", deskripsi: "iPhone adalah ponsel stylist yang
pernah ada", harga: 100, gambar: "pendrive.png"), ProductBox(
ProductBox( nama:
"iPhone", deskripsi: "iPhone adalah ponsel stylist yang pernah
ada", harga: 1000, gambar: "iphone.png"),
ProductBox( nama:
"iPhone", deskripsi: "iPhone adalah ponsel stylist yang pernah
ada", harga: 1000, gambar: "iphone.png"),
], ));
}
}
53
Machine Translated by Google
Berdebar
int _peringkat = 0;
batal _setRatingAsOne()
{ setState( () { _rating = 1; });
batal _setRatingAsTwo() {
setState( ()
{ _rating = 2; });
batal _setRatingAsThree()
{ setState( () { _rating = 3; });
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton(
54
Machine Translated by Google
Berdebar
warna: Warna.merah[500],
onPressed: _setRatingAsThree,
iconSize: _size, ), ),
], );
}
}
MainAxisAlignment.spaceMerata,
anak-anak:
<Widget>[ Text(ini.nama,
gaya: TextStyle(fontWeight:
FontWeight.bold)),
Text(this.description),
Text("Harga: " + this.price.toString()), RatingBox(), ], )))
])));
}
}
55
Machine Translated by Google
Berdebar
• Terakhir, jalankan aplikasi dan lihat halaman State management - Product list
Hasil seperti yang ditunjukkan di sini:
56
Machine Translated by Google
Berdebar
Mengklik bintang peringkat akan memperbarui peringkat produk. Misalnya, pengaturan peringkat 2 bintang
untuk iPhone akan menampilkan peringkat seperti di bawah ini:
scoped_model menyediakan tiga kelas utama untuk mengaktifkan manajemen status yang kuat dalam aplikasi
yang dibahas secara mendetail di sini:
Model
Model merangkum keadaan aplikasi. Kita dapat menggunakan Model sebanyak mungkin (dengan mewarisi
kelas Model) sesuai kebutuhan untuk mempertahankan status aplikasi. Ia memiliki metode tunggal,
notifyListeners, yang perlu dipanggil setiap kali status Model berubah. notifyListeners akan melakukan hal-hal
yang diperlukan untuk memperbarui UI.
57
Machine Translated by Google
Berdebar
notifyListeners();
}
}
ScopedModel
ScopedModel adalah sebuah widget, yang menyimpan model yang diberikan dan meneruskannya ke semua
widget turunan jika diminta. Jika diperlukan lebih dari satu model, maka kita perlu menyarangkan
ScopedModel.
• Model tunggal
ScopedModel<Produk>( model:
item, anak: AnyWidget()
• Model ganda
ScopedModel<Produk>( model:
item1, anak:
ScopedModel<Produk>( model:
item2, anak: AnyWidget(), ),
ScopedModel.of adalah metode yang digunakan untuk mendapatkan model yang mendasari ScopedModel.
Ini dapat digunakan saat tidak ada perubahan UI yang diperlukan meskipun model akan berubah. Berikut ini
tidak akan mengubah UI (peringkat) produk.
ScopedModel.of<Produk>(konteks).updateRating(2);
58
Machine Translated by Google
Berdebar
ScopedModelDescendant
ScopedModelDescendant adalah widget, yang mendapatkan model dari widget tingkat atas, ScopedModel, dan
membangun antarmuka penggunanya setiap kali model berubah.
ScopedModelDescendant memiliki dua properti – pembangun dan anak. anak adalah bagian UI yang tidak berubah
dan akan diteruskan ke pembangun. builder menerima fungsi dengan tiga argumen:
kembalikan ScopedModelDescendant<ProductModel>(
pembangun: (konteks, anak, keranjang) => { ... UI Aktual ... }, anak: PartOfTheUI(), );
Mari kita ubah sampel kita sebelumnya untuk menggunakan scoped_model daripada StatefulWidget
berdebar:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/pendrive.png
- aset/appimages/pixel.png - aset/appimages/
tablet.png
• Konfigurasikan paket scoped_model pada file pubspec.yaml seperti gambar di bawah ini:
dependensi:
scoped_model: ^1.0.1
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan mengonfigurasinya
dengan benar untuk aplikasi tersebut.
59
Machine Translated by Google
Berdebar
import 'package:flutter/material.dart';
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
Text( 'Hello World', )),
);
}
}
import 'package:scoped_model/scoped_model.dart';
• Mari kita buat kelas Produk, Product.dart untuk mengatur informasi produk.
import 'package:scoped_model/scoped_model.dart';
60
Machine Translated by Google
Berdebar
notifyListeners();
}
}
Di sini, kami menggunakan notifyListeners untuk mengubah UI setiap kali peringkat diubah.
• Mari kita tulis metode getProducts di kelas Produk untuk menghasilkan dummy kita
catatan produk.
items.add(Product( "Pixel",
"Pixel adalah
ponsel paling lengkap fitur yang pernah ada", 800,
"pixel.png", 0));
item.tambahkan(Produk(
61
Machine Translated by Google
Berdebar
"Floppy Drive",
"Floppy drive adalah media penyimpanan penyelamat yang
berguna", 20, "floppy.png", 0));
mengembalikan barang;
}
impor product.dart di main.dart
impor 'Produk.dart';
• Mari kita ubah widget baru kita, RatingBox untuk mendukung konsep scoped_model.
return
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton( icon: (item.rating >= 1 ? Ikon(Ikon.bintang,
ukuran: _ukuran,
)
:
Ikon( Icons.star_border,
size: _size, )), warna:
Colors.red[500],
onPressed: () =>
this.item.updateRating(1), iconSize: _size, ), ),
Container( padding: EdgeInsets.all(0), anak:
IconButton( icon: (item.rating >= 2 ? Icon( Icons.star,
ukuran: _size,
)
:
Ikon( Icons.star_border,
ukuran: _size,
62
Machine Translated by Google
Berdebar
)),
warna: Colors.red[500],
onPressed: () => this.item.updateRating(2), iconSize:
_size, ), ), Container( padding: EdgeInsets.all(0), child:
IconButton( ikon: (item.rating >= 3 ? Ikon( Bintang ikon,
ukuran: _ukuran,
)
:
Ikon( Ikon.bintang_border,
ukuran: _ukuran, )),
warna: Warna.merah[500],
onPressed: () =>
this.item.updateRating(3), ukuran ikon: _ukuran, ), ], );
}
}
• Mari kita memodifikasi widget ProductBox kita untuk bekerja dengan Product, ScopedModel dan
Kelas ScopedModelDescendant.
63
Machine Translated by Google
Berdebar
mainAxisAlignment:
MainAxisAlignment.spaceEvenly, anak-anak: <Widget>[
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Teks(ini.item.deskripsi), Teks("Harga:
" +
this.item.price.toString()),
ScopedModelDescendant<Produk>(
pembangun: (konteks, anak, item) {
return RatingBox(item: item); }) ], ))))
]),
));
}
}
Di sini, kami telah menggabungkan widget RatingBox di dalam ScopedModel dan ScopedModelDecendant.
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Navigation")), body: ListView.builder(
itemCount: items.length,
itemBuilder: (konteks, indeks) { return
ProductBox(item: item[indeks]); }, ));
}
}
Di sini, kami telah menggunakan ListView.builder untuk membuat daftar produk kami secara dinamis.
Produk.dart
import 'package:scoped_model/scoped_model.dart';
64
Machine Translated by Google
Berdebar
batal cn
"Laptop adalah alat pengembangan paling produktif", 2000,
"laptop.png", 0));
items.add(Product( "Floppy
Drive", "Floppy
drive adalah media penyimpanan penyelamat yang berguna",
20, "floppy.png", 0));
mengembalikan barang;
}
}
main.dart
65
Machine Translated by Google
Berdebar
@mengesampingkan
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Navigation")), body: ListView.builder(
itemCount: items.length,
itemBuilder: (konteks, indeks) { return
ProductBox(item: item[indeks]); }, ));
}
}
return
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton( icon: (item.rating >= 1 ? Ikon(Ikon.bintang,
ukuran: _ukuran,
)
: Ikon(
66
Machine Translated by Google
Berdebar
Icons.star_border,
size: _size, )), color:
Colors.red[500],
onPressed: () =>
this.item.updateRating(1), iconSize: _size, ), ),
Container( padding: EdgeInsets.all (0), anak:
IconButton( icon: (item.rating >= 2 ? Icon( Icons.star,
ukuran: _size,
)
:
Ikon( Icons.star_border,
size: _size, )), warna:
Colors.red[500],
onPressed: () =>
this.item.updateRating(2), iconSize: _size, ), ),
Container( padding: EdgeInsets.all(0), anak:
IconButton( icon: (item.rating >= 3 ? Icon( Icons.star,
ukuran: _size,
)
:
Ikon( Ikon.bintang_border,
ukuran: _ukuran, )),
warna: Warna.merah[500],
onPressed: () =>
this.item.updateRating(3), ukuran ikon: _ukuran, ), ], );
}
}
67
Machine Translated by Google
Berdebar
tinggi: 140,
anak:
Kartu( anak: Baris(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, anak-
anak: <Widget>[ Image.asset("assets/appimages/" +
this.item.image), Diperluas( anak: Kontainer( padding:
EdgeInsets.all(5), anak: ScopedModel<Produk >( model:
this.item, anak: Kolom( mainAxisAlignment:
MainAxisAlignment.spaceEvenly, anak: <Widget>[
Teks(nama.item.ini,
gaya: TextStyle(Berat
font:
FontWeight.bold)),
Teks(ini.item.deskripsi),
Teks("Harga: " +
this.item.price.toString()),
ScopedModelDescendant<Produk>(
pembangun: (konteks, anak, item) {
return RatingBox(item: item); }) ], ))))
]),
));
}
}
Terakhir, kompilasi dan jalankan aplikasi untuk melihat hasilnya. Ini akan bekerja mirip dengan contoh
sebelumnya kecuali aplikasi menggunakan konsep scoped_model.
MaterialPageRoute
MaterialPageRoute adalah widget yang digunakan untuk merender UI-nya dengan mengganti seluruh layar
dengan animasi khusus platform.
Di sini, pembangun akan menerima fungsi untuk membangun kontennya dengan melengkapi konteks
aplikasi saat ini.
Navigasi.push
68
Machine Translated by Google
Berdebar
Navigator.push( konteks,
Navigasi.pop
Navigation.pop digunakan untuk menavigasi ke layar sebelumnya.
Navigator.push(konteks);
Mari kita buat aplikasi baru untuk lebih memahami konsep navigasi.
berdebar:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/
pendrive.png - aset/appimages/pixel.png -
aset/appimages/tablet.png
import 'package:flutter/material.dart';
}
}
69
Machine Translated by Google
Berdebar
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
Text( 'Hello World', )),
);
}
}
kelas Produk
{ nama String akhir;
deskripsi String akhir; harga int
akhir; gambar String akhir;
• Mari kita tulis metode getProducts di kelas Produk untuk menghasilkan dummy kita
catatan produk.
items.add(Product( "Pixel",
"Pixel adalah
ponsel dengan fitur paling lengkap", 800, "pixel.png"));
items.add(Product( "Tablet",
"Tablet adalah
perangkat yang paling berguna untuk rapat", 1500, "tablet.png"));
70
Machine Translated by Google
Berdebar
100,
"pendrive.png"));
items.add(Product( "Floppy
Drive", "Floppy
drive adalah media penyimpanan penyelamat yang berguna",
20, "floppy.png"));
mengembalikan barang;
}
impor product.dart di main.dart
impor 'Produk.dart';
batal _setRatingAsOne()
{ setState(() { _rating = 1; });
batal _setRatingAsTwo()
{ setState(() { _rating = 2; });
batal _setRatingAsThree() {
setState(()
{ _rating = 3; });
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0), anak:
IconButton(
71
Machine Translated by Google
Berdebar
}
}
72
Machine Translated by Google
Berdebar
• Mari kita memodifikasi widget ProductBox kita untuk bekerja dengan kelas Produk baru kita.
anak-anak: <Widget>[
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Text(this.item.description),
Text("Harga: " + this.item.price.toString()), RatingBox(), ], )))
]),
));
}
}
• Mari kita menulis ulang widget MyHomePage kita untuk bekerja dengan model Produk dan untuk membuat daftar
semua produk menggunakan ListView.
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Navigation")), body: ListView.builder(
itemCount: item.panjang,
itemBuilder: (konteks, indeks) {
73
Machine Translated by Google
Berdebar
), ); }, ); }, ));
}
}
Di sini, kami telah menggunakan MaterialPageRoute untuk menavigasi ke halaman detail produk.
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.item.name), ), body: Center( child:
Container( padding: EdgeInsets.all(0),
anak:
Kolom( mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, anak:
<Widget>[ Image.asset("assets/appimages/" +
this.item.image),
Diperluas( anak:
Kontainer( padding: EdgeInsets.all(5),
anak: Kolom( mainAxisAlignment:
MainAxisAlignment.spaceMerata,
anak-anak: <Widget>[
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Teks(ini.item.deskripsi), Teks("Harga:
" +
this.item.price.toString()),
RatingBox(),
74
Machine Translated by Google
Berdebar
], )))
]),
),
), );
}
}
import 'package:flutter/material.dart';
kelas Produk
{ nama String akhir;
deskripsi String akhir; harga int
akhir; gambar String akhir;
items.add(Product( "Pixel",
"Pixel adalah ponsel paling berfitur yang pernah ada", 800,
"piksel.png"));
2000, "laptop.png"));
items.add(Product( "Tablet",
"Tablet adalah
perangkat yang paling berguna untuk rapat", 1500, "tablet.png"));
items.add(Product( "Floppy
Drive", "iPhone adalah ponsel stylist yang pernah ada", 20, "floppy.png"));
mengembalikan barang;
}
}
75
Machine Translated by Google
Berdebar
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Navigation")), body: ListView.builder(
itemCount: items.length,
itemBuilder: (konteks, indeks) { return
GestureDetector( anak:
ProductBox(item: item[indeks]), onTap: ()
{ Navigator.push( konteks, MaterialPageRoute(
), ); }, ); }, ));
}
}
@mengesampingkan
76
Machine Translated by Google
Berdebar
MainAxisAlignment.spaceMerata,
anak-anak: <Widget>[
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Teks(ini.item.deskripsi), Teks("Harga:
" +
this.item.price.toString()),
RatingBox(), ], )))
]),
),
), );
}
}
batal _setRatingAsOne()
{ setState(() { _rating = 1; });
batal _setRatingAsTwo()
{ setState(() { _rating = 2; });
batal _setRatingAsThree()
{ setState(() {
77
Machine Translated by Google
Berdebar
_peringkat =
3; });
}
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0),
anak: IconButton(
78
Machine Translated by Google
Berdebar
:
Ikon( Icons.star_border,
ukuran: _ukuran, )),
warna: Warna.merah[500],
onPressed: _setRatingAsThree,
iconSize: _size, ), ), ], );
}
}
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Text(this.item.description),
Text("Harga: " + this.item.price.toString()), RatingBox(), ], )))
]),
));
}
}
79
Machine Translated by Google
Berdebar
Jalankan aplikasi dan klik salah satu item produk. Ini akan menampilkan halaman detail yang relevan. Kita bisa pindah
ke halaman rumah dengan mengklik tombol kembali. Halaman daftar produk dan halaman detail produk aplikasi
ditampilkan sebagai berikut:
80
Machine Translated by Google
Berdebar
81
Machine Translated by Google
Animasi adalah prosedur kompleks dalam aplikasi seluler apa pun. Terlepas dari kerumitannya,
Animasi meningkatkan pengalaman pengguna ke tingkat yang baru dan menyediakan interaksi
pengguna yang kaya. Karena kekayaannya, animasi menjadi bagian integral dari aplikasi seluler
modern. Kerangka kerja Flutter mengakui pentingnya Animasi dan menyediakan kerangka kerja yang
sederhana dan intuitif untuk mengembangkan semua jenis animasi.
Perkenalan
Animasi adalah proses menampilkan rangkaian gambar/gambar dalam urutan tertentu dalam durasi
tertentu untuk memberikan ilusi gerakan. Aspek yang paling penting dari animasi adalah sebagai
berikut:
• Animasi memiliki dua nilai yang berbeda: nilai awal dan nilai akhir. Animasi dimulai dari nilai Mulai
dan melewati serangkaian nilai perantara dan akhirnya berakhir pada nilai Akhir . Misalnya,
untuk menganimasikan widget agar menghilang, nilai awal adalah opasitas penuh dan nilai akhir
adalah opasitas nol.
• Nilai-nilai perantara mungkin bersifat linier atau non-linier (kurva) dan dapat dikonfigurasi. Pahami
bahwa animasi berfungsi seperti yang dikonfigurasi. Setiap konfigurasi memberikan nuansa
berbeda pada animasi. Misalnya, memudar widget akan bersifat linier sedangkan pantulan bola
akan bersifat non-linier.
• Durasi proses animasi mempengaruhi kecepatan (slowness atau fastness) dari animasi tersebut
animasi.
• Kemampuan untuk mengontrol proses animasi seperti memulai animasi, menghentikan animasi,
mengulang animasi untuk mengatur berapa kali, membalikkan proses animasi, dll.,
• Di Flutter, sistem animasi tidak melakukan animasi nyata. Alih-alih, ini hanya memberikan nilai
yang diperlukan di setiap bingkai untuk merender gambar.
Animasi
Menghasilkan nilai interpolasi antara dua angka selama durasi tertentu. Kelas Animasi yang paling
umum adalah:
82
Machine Translated by Google
Berdebar
• AnimationController - Objek Animasi Khusus untuk mengontrol animasi itu sendiri. Ini menghasilkan nilai baru setiap
kali aplikasi siap untuk bingkai baru. Ini mendukung animasi berbasis linier dan nilainya mulai dari 0,0 hingga 1,0.
Di sini, pengontrol mengontrol animasi dan opsi durasi mengontrol durasi proses animasi. vsync adalah opsi
khusus yang digunakan untuk mengoptimalkan sumber daya yang digunakan dalam animasi.
CurvedAnimation
Mirip dengan AnimationController tetapi mendukung animasi non-linear. CurvedAnimation dapat digunakan bersama
dengan objek Animation seperti di bawah ini:
Dua <T>
Berasal dari Animatable<T> dan digunakan untuk menghasilkan angka antara dua angka selain 0 dan 1. Ini dapat
digunakan bersama dengan objek Animation dengan menggunakan metode animate dan meneruskan objek Animation
yang sebenarnya.
Tween juga dapat digunakan bersama dengan CurvedAnimation seperti di bawah ini:
Di sini, pengontrol adalah pengontrol animasi yang sebenarnya. kurva memberikan jenis non-linearitas dan customTween
menyediakan rentang kustom dari 0 hingga 255.
83
Machine Translated by Google
Berdebar
nilai. });
});
Widget bawaan, AnimatedWidget dan AnimatedBuilder dapat digunakan untuk melewati proses ini. Kedua
widget menerima objek Animasi dan mendapatkan nilai saat ini yang diperlukan untuk animasi.
• Dapatkan nilai animasi selama proses pembuatan widget, lalu terapkan untuk lebar, tinggi, atau properti apa
pun yang relevan, bukan nilai aslinya.
Aplikasi Kerja
Mari kita menulis aplikasi berbasis animasi sederhana untuk memahami konsep animasi dalam framework Flutter.
• Salin folder aset dari product_nav_app ke product_animation_app dan tambahkan aset di dalam file
pubspec.yaml
berdebar:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/
pendrive.png - aset/appimages/pixel.png -
aset/appimages/tablet.png
import 'package:flutter/material.dart';
84
Machine Translated by Google
Berdebar
• Buat widget _MyAppState dan implementasikan initState dan buang selain metode build default.
Animasi<double> animasi;
Pengontrol AnimationController;
@override
void initState() {
super.initState();
controller = AnimationController(durasi: Durasi const(detik: 10), vsync: ini);
);
}
@override
void buang()
{ controller.dispose();
super.buang();
}
}
Di Sini,
• Dalam metode initState, kami telah membuat objek pengontrol animasi (controller), objek animasi
(animation) dan memulai animasi menggunakan controller.forward.
• Dalam metode buang, kita telah membuang objek pengendali animasi (controller).
• Dalam metode build, kirim animasi ke widget MyHomePage melalui konstruktor. Sekarang, widget
MyHomePage dapat menggunakan objek animasi untuk menganimasikan kontennya.
85
Machine Translated by Google
Berdebar
: super(kunci: kunci);
FontWeight.bold)),
Teks(ini.deskripsi),
Teks("Harga: " + ini.harga.toString()), ], )))
])));
}
}
• Buat widget baru, MyAnimatedWidget untuk melakukan animasi fade sederhana menggunakan opacity.
);
}
• Di sini, kami telah menggunakan AniatedBuilder untuk melakukan animasi kami. AnimatedBuilder
adalah widget yang membangun kontennya sambil melakukan animasi pada saat yang bersamaan.
Itu menerima objek animasi untuk mendapatkan nilai animasi saat ini. Kami telah menggunakan animasi
86
Machine Translated by Google
Berdebar
value, animation.value untuk mengatur opacity widget anak. Efeknya, widget akan menganimasikan
widget anak menggunakan konsep opacity.
• Terakhir, buat widget MyHomePage dan gunakan objek animasi untuk menganimasikan kontennya.
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Listing")), body: ListView( shrinkWrap: true, padding: const
EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0) , anak-anak:
<Widget>[ FadeTransition(anak: ProductBox( nama: "iPhone",
deskripsi: "iPhone adalah ponsel stylist yang pernah ada", harga: 1000,
gambar: "iphone.png"), opacity: animasi), MyAnimatedWidget( anak:
ProductBox( nama: "Pixel", deskripsi: "Pixel adalah ponsel paling berfitur
yang pernah ada", harga: 800, gambar: "pixel.png"),
animasi: animasi),
ProductBox( nama: "Laptop",
deskripsi: "Laptop
adalah alat pengembangan paling produktif", harga: 2000, gambar: "laptop.png"),
ProductBox( nama: "Tablet", deskripsi: "Tablet adalah perangkat paling berguna
yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama: "Flashdisk",
deskripsi: "Flashdisk adalah
media penyimpanan yang berguna", harga: 100, gambar:
"pendrive.png"), ProductBox( nama: "Floppy Drive", deskripsi:
"Floppy drive adalah penyimpanan penyelamat yang berguna
sedang",
harga: 20,
gambar: "floppy.png"),
],
87
Machine Translated by Google
Berdebar
));
}
}
Di sini, kami telah menggunakan FadeAnimation dan MyAnimationWidget untuk menganimasikan dua
item pertama dalam daftar. FadeAnimation adalah kelas animasi bawaan, yang kami gunakan untuk
menganimasikan anaknya menggunakan konsep opacity.
import 'package:flutter/material.dart';
Animasi<double> animasi;
Pengontrol AnimationController;
@override
void initState() {
super.initState();
controller = AnimationController(durasi: Durasi const(detik: 10), vsync: ini); animasi =
Tween<double>(mulai: 0.0, akhir: 1.0).animate(pengontrol); controller.maju();
);
}
@override
void buang()
{ controller.dispose();
super.buang();
}
}
88
Machine Translated by Google
Berdebar
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar(title: Text("Product
Listing")), body: ListView( shrinkWrap: true, padding: const
EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0) , anak-anak:
<Widget>[ FadeTransition(anak: ProductBox( nama:
"iPhone", deskripsi: "iPhone adalah ponsel stylist yang pernah ada", harga:
1000, gambar: "iphone.png"), opacity: animasi), MyAnimatedWidget( anak:
ProductBox( nama: "Pixel", deskripsi: "Pixel adalah ponsel paling berfitur
yang pernah ada", harga: 800, gambar: "pixel.png"),
animasi: animasi),
ProductBox( nama: "Laptop",
deskripsi: "Laptop
adalah alat pengembangan paling produktif", harga: 2000, gambar:
"laptop.png"), ProductBox( nama: "Tablet", deskripsi: "Tablet adalah perangkat
paling berguna yang pernah ada
pertemuan",
harga: 1500,
gambar: "tablet.png"),
ProductBox( nama:
"Flashdisk", deskripsi: "Flashdisk adalah media penyimpanan
yang berguna", harga: 100, gambar: "flashdisk.png"), ProductBox(
], ));
}
}
89
Machine Translated by Google
Berdebar
FontWeight.bold)),
Teks(ini.deskripsi),
Teks("Harga: " + ini.harga.toString()), ], )))
])));
}
}
);
}
90
Machine Translated by Google
Berdebar
• Kompilasi dan jalankan aplikasi untuk melihat hasilnya. Versi awal dan akhir dari
aplikasinya adalah sebagai berikut:
91
Machine Translated by Google
Berdebar
92
Machine Translated by Google
Flutter menyediakan framework umum untuk mengakses fitur khusus platform. Hal ini memungkinkan
developer memperluas fungsionalitas framework Flutter menggunakan kode khusus platform.
Fungsi khusus platform seperti kamera, level baterai, browser, dll., dapat diakses dengan mudah melalui
framework.
Gagasan umum untuk mengakses kode khusus platform adalah melalui protokol perpesanan sederhana.
Kode Flutter, Klien dan kode platform serta Host terikat ke Saluran Pesan umum. Klien mengirim pesan ke
Host melalui Saluran Pesan. Host mendengarkan di Saluran Pesan, menerima pesan dan melakukan
fungsionalitas yang diperlukan dan akhirnya, mengembalikan hasilnya ke Klien melalui Saluran Pesan.
Arsitektur kode khusus platform ditunjukkan dalam diagram blok yang diberikan di bawah ini:
Protokol perpesanan menggunakan codec pesan standar (kelas StandardMessageCodec) yang mendukung
serialisasi biner dari nilai-nilai seperti JSON seperti angka, string, boolean, dll., Serialisasi dan de-serialisasi
bekerja secara transparan antara klien dan host.
Mari kita menulis aplikasi sederhana untuk membuka browser menggunakan Android SDK dan memahami
cara menjalankan SDK dari aplikasi flutter.
import 'package:flutter/material.dart';
93
Machine Translated by Google
Berdebar
);
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
RaisedButton( child: Text('Open
Browser'), onPressed: null, ) , ), );
}
}
• Di sini, kami telah membuat tombol baru untuk membuka browser dan menetapkan metode
onPressed sebagai null.
import 'dart:async';
import 'package:flutter/services.dart';
• Tulis metode, _openBrowser untuk memanggil metode khusus platform, metode openBrowser melalui
saluran pesan.
94
Machine Translated by Google
Berdebar
Di sini, kami telah menggunakan platform.invokeMethod untuk memanggil openBrowser (dijelaskan di langkah
selanjutnya). openBrowser memiliki argumen, url untuk membuka url tertentu.
• Ubah nilai properti onPressed dari RaisedButton dari null menjadi _openBrowser.
onPressed: _openBrowser,
• Buka MainActivity.java (di dalam folder android) dan impor pustaka yang diperlukan:
private void openBrowser(MethodCall call, Result result, String url) {Aktivitas aktivitas = ini;
if (aktivitas == null) { result.error("ACTIVITY_NOT_AVAILABLE", "Browser tidak dapat
dibuka
aktivitas.startActivity(niat);
hasil.sukses((Objek) benar);
}
• Tulis kode khusus android untuk mengatur penanganan pesan dalam metode onCreate.
if (call.method.equals("openBrowser")) {
95
Machine Translated by Google
Berdebar
}
});
Di sini, kami telah membuat saluran pesan menggunakan kelas MethodChannel dan menggunakan kelas
MethodCallHandler untuk menangani pesan. onMethodCall adalah metode aktual yang bertanggung jawab
untuk memanggil kode spesifik platform yang benar dengan memeriksa pesan. metode onMethodCall
mengekstrak url dari pesan dan kemudian memanggil openBrowser hanya ketika panggilan metode adalah
openBrowser. Jika tidak, ia mengembalikan metode notImplemented.
main.dart
MainActivity.java
paket com.tutorialspoint.flutterapp.flutter_browser_app;
@Override
protected void onCreate(Bundle storedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(ini);
if (call.method.equals("openBrowser"))
{ openBrowser(call, result, url); } else
{ result.notImplemented();
96
Machine Translated by Google
Berdebar
});
}
aktivitas.startActivity(niat);
hasil.sukses((Objek) benar);
}
}
main.dart
import 'package:flutter/material.dart';
}
}
97
Machine Translated by Google
Berdebar
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
RaisedButton( child: Text('Open
Browser'), onPressed: _openBrowser, ) , ), );
}
}
Jalankan aplikasi dan klik tombol Buka Browser dan Anda dapat melihat bahwa browser diluncurkan.
Aplikasi Browser - Beranda seperti yang ditunjukkan pada tangkapan layar di sini:
98
Machine Translated by Google
Berdebar
99
Machine Translated by Google
Berdebar
12. Flutter – Menulis Kode Khusus iOS
Mengakses kode khusus iOS mirip dengan yang ada di platform Android kecuali menggunakan bahasa khusus
iOS - Objective-C atau Swift dan iOS SDK. Kalau tidak, konsepnya sama dengan platform Android.
Mari kita menulis aplikasi yang sama seperti pada bab sebelumnya untuk platform iOS juga.
• Mari kita buat aplikasi baru di Android Studio (macOS), flutter_browser_ios_app
• Pilih proyek xcode di bawah direktori ios dari proyek flutter kami.
• Buka AppDelegate.m di bawah Runner -> Runner path. Ini berisi berikut ini
kode:
#termasuk "AppDelegate.h"
#termasuk "GeneratedPluginRegistrant.h"
@implementasi AppDelegate
//
@akhir
• Kami telah menambahkan metode, openBrowser untuk membuka browser dengan url tertentu. Dia
menerima argumen tunggal, url.
- (kosongkan)bukaBrowser:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
UIApplication *application = [UIApplication sharedApplication];
[aplikasi openURL:url];
}
• Dalam metode didFinishLaunchingWithOptions, temukan pengontrol dan atur dalam variabel pengontrol.
100
Machine Translated by Google
Berdebar
Pengontrol FlutterViewController* =
(FlutterViewController*)self.window.rootViewController;
methodChannelWithName:@"flutterapp.tutorialspoint.com/browser"
binaryMessenger:pengontrol];
}
}];
#termasuk "AppDelegate.h"
#termasuk "GeneratedPluginRegistrant.h"
@implementasi AppDelegate
(FlutterViewController*)self.window.rootViewController;
methodChannelWithName:@"flutterapp.tutorialspoint.com/browser"
binaryMessenger:pengontrol];
101
Machine Translated by Google
Berdebar
}
}];
- (kosongkan)bukaBrowser:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
UIApplication *application = [UIApplication sharedApplication];
[aplikasi openURL:url];
}
@akhir
• Sekarang, jalankan aplikasi. Ini berfungsi mirip dengan versi Android tetapi browser Safari akan dibuka,
bukan chrome.
102
Machine Translated by Google
Cara Dart mengatur dan berbagi serangkaian fungsi adalah melalui Paket. Paket Dart hanyalah pustaka
atau modul yang dapat dibagikan. Secara umum Paket Dart sama dengan Aplikasi Dart hanya saja Paket
Dart tidak memiliki titik masuk aplikasi, utama.
Struktur umum Paket (pertimbangkan paket demo, my_demo_package) adalah sebagai berikut:
• lib/my_demo_package.dart: File kode Dart utama. Itu dapat diimpor ke aplikasi sebagai:
ekspor src/my_private_code.dart
• lib/* : Sejumlah file kode Dart yang diatur dalam struktur folder kustom apa pun. Kode dapat diakses
sebagai,
Semua file kode Dart dalam Paket hanyalah kelas Dart dan tidak memiliki persyaratan khusus untuk kode
Dart untuk memasukkannya ke dalam Paket.
Jenis Paket
Karena Paket Dart pada dasarnya adalah kumpulan kecil dari fungsi serupa, itu dapat dikategorikan
berdasarkan fungsinya.
Paket Dart
Kode Dart generik, yang dapat digunakan di lingkungan web dan seluler. Misalnya, english_words adalah
salah satu paket yang berisi sekitar 5000 kata dan memiliki fungsi utilitas dasar seperti kata benda (daftar
kata benda dalam bahasa Inggris), suku kata (sebutkan jumlah suku kata dalam sebuah kata.
Paket Flutter
Kode Dart umum, yang bergantung pada framework Flutter dan hanya dapat digunakan di lingkungan seluler.
Misalnya, fluro adalah router khusus untuk flutter. Itu tergantung pada kerangka kerja Flutter.
103
Machine Translated by Google
Berdebar
Plugin Bergetar
Kode Dart generik, yang bergantung pada framework Flutter serta kode platform yang mendasarinya (SDK Android atau SDK
iOS). Misalnya, kamera adalah plugin untuk berinteraksi dengan kamera perangkat. Itu tergantung pada framework Flutter
serta framework yang mendasarinya untuk mendapatkan akses ke kamera.
• Sertakan nama paket dan versi yang dibutuhkan ke dalam pubspec.yaml seperti yang ditunjukkan
di bawah:
dependensi:
english_words: ^3.1.5
• Saat mengembangkan di studio Android, Android Studio mendeteksi setiap perubahan di pubspec.yaml dan
menampilkan peringatan paket Android studio kepada pengembang seperti yang ditunjukkan di bawah ini:
• Paket Dart dapat diinstal atau diperbarui di Android Studio menggunakan opsi menu.
• Impor file yang diperlukan menggunakan perintah yang ditunjukkan di bawah ini dan mulai bekerja:
import 'package:english_words/english_words.dart';
kata benda.ambil(50).untukMasing-masing(cetak);
• Di sini, kami telah menggunakan fungsi kata benda untuk mendapatkan dan mencetak 50 kata teratas.
Seperti yang telah kita pelajari cara mengakses kode platform di bab sebelumnya, mari kita kembangkan sebuah plugin
sederhana, my_browser untuk memahami proses pengembangan plugin. Itu
104
Machine Translated by Google
Berdebar
fungsionalitas plugin my_browser adalah untuk memungkinkan aplikasi membuka situs web yang diberikan di
browser khusus platform.
• Klik File -> New Flutter Project dan pilih opsi Flutter Plugin.
• Anda dapat melihat jendela pemilihan plugin Flutter seperti yang ditunjukkan di sini:
105
Machine Translated by Google
Berdebar
• Masukkan nama plugin dan detail lainnya di jendela seperti yang ditunjukkan di sini:
106
Machine Translated by Google
Berdebar
• Buka file my_browser.dart dan tulis metode, openBrowser untuk memanggil platform
metode openBrowser tertentu.
• Di sini, kita harus mengimpor library yang diperlukan untuk membuka browser dari Android.
• Tambahkan mRegistrar variabel pribadi baru dari tipe Registrar di kelas MyBrowserPlugin.
• Di sini, Registrar digunakan untuk mendapatkan informasi konteks dari kode pemanggilan.
@Override
public void onMethodCall(Panggilan MethodCall, Hasil hasil) {
107
Machine Translated by Google
Berdebar
if (call.method.equals("getPlatformVersion"))
{ result.success("Android " + android.os.Build.VERSION.RELEASE); } else if
(call.method.equals("openBrowser")) {
openBrowser(panggilan, hasil, url); }
else { result.notImplemented();
}
}
aktivitas.startActivity(niat);
hasil.sukses((Objek) benar);
}
my_browser.dart
import 'dart:async';
import 'package:flutter/services.dart';
108
Machine Translated by Google
Berdebar
}
}
MyBrowserPlugin.java
paket com.tutorialspoint.flutterplugins.my_browser;
@Override
public void onMethodCall(Panggilan MethodCall, Hasil hasil) {
String url = call.argument("url");
if (call.method.equals("getPlatformVersion"))
{ result.success("Android " + android.os.Build.VERSION.RELEASE); } else if
(call.method.equals("openBrowser")) {
openBrowser(panggilan, hasil, url); }
else { result.notImplemented();
}
}
109
Machine Translated by Google
Berdebar
aktivitas.startActivity(niat);
hasil.sukses((Objek) benar);
}
}
• Buat proyek baru, my_browser_plugin_test untuk menguji plugin kita yang baru dibuat.
dependensi:
bergetar:
sdk: bergetar
my_browser:
jalur: ../my_browser
• Android studio akan memberi tahu bahwa pubspec.yaml diperbarui seperti yang ditunjukkan dalam peringatan
paket Android studio yang diberikan di bawah ini:
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan
mengonfigurasinya dengan benar untuk aplikasi tersebut.
import 'package:my_browser/my_browser.dart';
• Panggil fungsi openBrowser dari plugin my_browser seperti yang ditunjukkan di bawah ini:
110
Machine Translated by Google
Berdebar
}
}
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title:
Text(this.title), ), body: Center( child:
RaisedButton( child: Text('Buka
Browser'), onPressed: () = >
MyBrowser().openBrowser("https://
flutter.dev"), ), ), );
}
}
111
Machine Translated by Google
Berdebar
• Jalankan aplikasi dan klik tombol Buka Browser dan lihat bahwa browser diluncurkan. Anda dapat melihat aplikasi Browser
- Beranda seperti yang ditunjukkan pada tangkapan layar yang ditunjukkan di bawah ini:
112
Machine Translated by Google
Berdebar
• Anda dapat melihat aplikasi Browser – Layar browser seperti yang ditunjukkan pada tangkapan layar yang ditampilkan
di bawah:
113
Machine Translated by Google
Berdebar
14. Flutter – Mengakses REST API
Flutter menyediakan paket http untuk menggunakan sumber daya HTTP. http adalah pustaka berbasis masa depan dan
menggunakan fitur await dan async. Ini menyediakan banyak metode tingkat tinggi dan menyederhanakan pengembangan
aplikasi seluler berbasis REST.
Konsep dasar
Paket http menyediakan kelas tingkat tinggi dan http untuk melakukan permintaan web.
• Kelas http menyediakan fungsionalitas untuk melakukan semua jenis permintaan HTTP.
• Metode http menerima url, dan informasi tambahan melalui Dart Map (data posting, header tambahan, dll.,). Itu
meminta server dan mengumpulkan respons kembali dalam pola async/menunggu. Misalnya, kode di bawah ini
membaca data dari url yang ditentukan dan mencetaknya di konsol.
print(menunggu http.read('https://flutter.dev/'));
• baca - Minta url yang ditentukan melalui metode GET dan kembalikan respons sebagai Future<String>
• get - Minta url yang ditentukan melalui metode GET dan kembalikan respons sebagai Future<Response>. Response
adalah kelas yang menyimpan informasi respon.
• post - Meminta url yang ditentukan melalui metode POST dengan memposting data yang disediakan dan
mengembalikan respons sebagai Future<Response>
• put - Minta url yang ditentukan melalui metode PUT dan kembalikan responsnya
sebagai Masa Depan<Respon>
• head - Minta url yang ditentukan melalui metode HEAD dan kembalikan
respon sebagai Future<Response>
• hapus - Minta url yang ditentukan melalui metode DELETE dan kembalikan
respon sebagai Future<Response>
http juga menyediakan kelas klien HTTP yang lebih standar, klien. klien mendukung koneksi persisten. Ini akan berguna
bila banyak permintaan yang akan dilakukan ke server tertentu. Itu harus ditutup dengan benar menggunakan metode
tutup. Kalau tidak, ini mirip dengan kelas http. Contoh kodenya adalah sebagai berikut:
114
Machine Translated by Google
Berdebar
Mengakses ProductserviceAPI
Mari kita buat aplikasi sederhana untuk mendapatkan data produk dari server web dan kemudian menampilkan
produk menggunakan ListView.
berdebar:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/
pendrive.png - aset/appimages/pixel.png -
aset/appimages/tablet.png
• Konfigurasikan paket http pada file pubspec.yaml seperti gambar di bawah ini:
dependensi: http:
^0.12.0+2
• Di sini, kita akan menggunakan paket http versi terbaru. Studio Android akan mengirimkan peringatan paket
bahwa pubspec.yaml telah diperbarui.
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan mengonfigurasinya
dengan benar untuk aplikasi tersebut.
• Buat file JSON baru, products.json dengan informasi produk seperti yang ditunjukkan di bawah ini:
[
{
"name": "iPhone",
"description": "iPhone adalah ponsel stylist yang pernah ada", "price":
1000, "image": "iphone.png"
},
{
"name": "Pixel",
"description": "Pixel adalah ponsel berfitur paling banyak", "price": 800,
"image": "pixel.png"
115
Machine Translated by Google
Berdebar
},
{
"name": "Laptop",
"description": "Laptop adalah alat pengembangan paling produktif", "price": 2000,
"image": "laptop.png"
},
{
"name": "Tablet",
"description": "Tablet adalah perangkat yang paling berguna untuk rapat", "price": 1500,
"image": "tablet.png"
},
{
"name": "Flashdisk",
"description": "Flashdisk adalah media penyimpanan yang berguna",
"price": 100, "image": "flashdisk.png"
},
{
"name": "Floppy Drive",
"description": "Floppy drive adalah media penyimpanan penyelamat yang berguna",
"price": 20, "image": "floppy.png"
}
]
• Jalankan server web apa pun dengan JSONWebServer sebagai direktori akarnya dan dapatkan jalur webnya.
Misalnya, http://192.168.184.1:8000/products.json. Kita dapat menggunakan server web apa saja seperti
apache, nginx dll.,
• Cara termudah adalah menginstal aplikasi http-server berbasis node. Ikuti langkah-langkah yang diberikan
di bawah ini untuk menginstal dan menjalankan aplikasi server http.
cd /jalur/ke/JSONWebServer
http-server . -p 8000
116
Machine Translated by Google
Berdebar
http://127.0.0.1:8000 Tekan
CTRL-C untuk menghentikan server
• Buat file baru, Product.dart di folder lib dan pindahkan kelas Produk ke dalamnya.
• Tulis konstruktor pabrik di kelas Produk, Product.fromMap untuk mengonversi Peta data yang
dipetakan menjadi objek Produk. Biasanya, file JSON akan diubah menjadi objek Dart Map dan
kemudian diubah menjadi objek yang relevan (Produk)
Produk( data['nama'],
data['deskripsi'],
data['harga'],
data['gambar'], );
}
kelas Produk
{ nama String akhir;
deskripsi String akhir; harga int
akhir; gambar String akhir;
}
}
• Tulis dua metode - parseProducts dan fetchProducts - di kelas utama untuk mengambil dan memuat
informasi produk dari server web ke dalam objek List<Product> .
if (response.statusCode == 200) {
return parseProducts(response.body); } else
{ throw Exception('Tidak dapat mengambil produk
dari REST API');
117
Machine Translated by Google
Berdebar
}
}
• Future digunakan untuk memuat informasi produk dengan malas. Pemuatan malas adalah konsep
untuk menunda eksekusi kode sampai diperlukan.
• json.decode digunakan untuk mendekode data JSON ke dalam objek Dart Map. Setelah data JSON
didekodekan, data tersebut akan diubah menjadi List<Product> menggunakan fromMap dari kelas
Produk.
• Di kelas MyApp, tambahkan variabel anggota baru, produk bertipe Future<Product> dan sertakan
dalam konstruktor.
...
• Di kelas MyHomePage, tambahkan produk variabel anggota baru dengan tipe Future<Product> dan
sertakan dalam konstruktor. Juga, hapus variabel item dan metode yang relevan, panggilan metode
getProducts. Menempatkan variabel produk dalam konstruktor. Ini akan memungkinkan untuk
mengambil produk dari Internet hanya sekali saat aplikasi pertama kali dijalankan.
• Ubah opsi beranda (MyHomePage) dalam metode build widget MyApp menjadi
mengakomodasi perubahan di atas:
rumah: MyHomePage
(judul: 'halaman muka demo Navigasi Produk', produk: produk),
• Buat widget baru, ProductBoxList untuk membuat daftar produk di halaman beranda.
118
Machine Translated by Google
Berdebar
@override
Widget build(Konteks BuildContext) { return
ListView.builder(
itemCount: items.length,
itemBuilder: (konteks, indeks) { return
GestureDetector( anak: ProductBox(item:
item[indeks]), onTap: () { Navigator.push( konteks,
MaterialPageRoute(
}
}
Perhatikan bahwa kami menggunakan konsep yang sama yang digunakan dalam aplikasi Navigasi untuk
mencantumkan produk kecuali itu dirancang sebagai widget terpisah dengan mengirimkan produk (objek)
bertipe List<Product>.
mengembalikan
snapshot.hasData ?
ProductBoxList( item: snapshot.data) // kembalikan widget ListView
: Pusat(anak: CircularProgressIndicator());
}, ), ));
}
• Di sini perhatikan bahwa kami menggunakan widget FutureBuilder untuk merender widget. FutureBuilder
akan mencoba mengambil data dari properti masa depan (tipe Future<List<Product>>).
Jika properti mendatang mengembalikan data, itu akan merender widget menggunakan ProductBoxList, jika
tidak akan menimbulkan kesalahan.
119
Machine Translated by Google
Berdebar
import 'package:flutter/material.dart';
impor 'Produk.dart';
if (response.statusCode == 200) {
return parseProducts(response.body); } else
{ throw Exception('Tidak dapat mengambil produk
dari REST API');
}
}
}
}
120
Machine Translated by Google
Berdebar
@mengesampingkan
if (snapshot.hasError) print(snapshot.error);
mengembalikan
snapshot.hasData ?
ProductBoxList( item: snapshot.data) // kembalikan widget ListView
: Pusat(anak: CircularProgressIndicator());
}, ), ));
}
}
@override
Widget build(Konteks BuildContext) { return
ListView.builder(
itemCount: items.length,
itemBuilder: (konteks, indeks) { return
GestureDetector( anak:
ProductBox(item: item[indeks]), onTap: ()
{ Navigator.push( konteks, MaterialPageRoute(
}
}
@mengesampingkan
121
Machine Translated by Google
Berdebar
anak-anak: <Widget>[
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Text(this.item.description),
Text("Harga: " + this.item.price.toString()), RatingBox(), ], )))
]),
), ), );
}
}
batal _setRatingAsOne()
{ setState(() { _rating = 1; });
batal _setRatingAsTwo()
{ setState(() { _rating = 2; });
batal _setRatingAsThree()
{ setState(() {
122
Machine Translated by Google
Berdebar
_peringkat =
3; });
}
kembalikan
Row( mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max, anak:
<Widget>[ Container( padding: EdgeInsets.all(0),
anak: IconButton(
123
Machine Translated by Google
Berdebar
:
Ikon( Icons.star_border,
ukuran: _ukuran, )),
warna: Warna.merah[500],
onPressed: _setRatingAsThree,
iconSize: _size, ), ), ], );
}
}
Teks(nama.item.ini, gaya:
TextStyle(Berat font:
FontWeight.bold)),
Text(this.item.description),
Text("Harga: " + this.item.price.toString()), RatingBox(), ], )))
]),
));
}
}
Terakhir jalankan aplikasi untuk melihat hasilnya. Ini akan sama dengan contoh Navigasi kami kecuali
datanya berasal dari Internet dan bukan dari lokal, data statis dimasukkan saat mengkode aplikasi.
124
Machine Translated by Google
Flutter menyediakan banyak paket lanjutan untuk bekerja dengan database. Paket yang paling penting adalah:
• firebase_database – Digunakan untuk mengakses dan memanipulasi database NoSQL yang dihosting cloud
dari Google.
SQLite
Basis data SQLite adalah mesin basis data tertanam berbasis SQL de-facto dan standar. Ini adalah mesin database
kecil dan teruji waktu. paket sqflite menyediakan banyak fungsi untuk bekerja secara efisien dengan database
SQLite. Ini menyediakan metode standar untuk memanipulasi mesin database SQLite. Fungsionalitas inti yang
disediakan oleh paket sqllite adalah sebagai berikut:
• Metode kueri tingkat lanjut (metode kueri) untuk direduksi menjadi kode yang diperlukan untuk kueri dan
dapatkan informasi dari database SQLite.
Mari kita membuat aplikasi produk untuk menyimpan dan mengambil informasi produk dari mesin database SQLite
standar menggunakan paket sqlite dan memahami konsep di balik database SQLite dan paket sqlite.
berdebar:
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/pendrive.png
- aset/appimages/pixel.png - aset/
appimages/tablet.png
• Konfigurasikan paket sqflite di file pubspec.yaml seperti yang ditunjukkan di bawah ini:
dependensi:
sqllite: apa saja
125
Machine Translated by Google
Berdebar
• Konfigurasikan paket path_provider pada file pubspec.yaml seperti gambar di bawah ini:
dependensi:
path_provider: apapun
• Di sini, paket path_provider digunakan untuk mendapatkan jalur folder sementara dari sistem dan
jalur aplikasi. Gunakan nomor versi terbaru dari sqflite sebagai pengganti .
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan
mengonfigurasinya dengan benar untuk aplikasi tersebut.
• Dalam database, kita membutuhkan primary key, id sebagai kolom tambahan bersama dengan
properti Produk seperti nama, harga, dll. Jadi, tambahkan properti id di kelas Produk. Juga, tambahkan
metode baru, toMap untuk mengonversi objek produk menjadi objek Peta. fromMap dan toMap
digunakan untuk serialisasi dan de-serialisasi objek Produk dan digunakan dalam metode manipulasi
basis data.
• Buat file baru, Database.dart di folder lib untuk menulis fungsionalitas terkait SQLite .
126
Machine Translated by Google
Berdebar
impor 'Produk.dart';
• path digunakan untuk mengakses fungsi utilitas inti dart yang terkait dengan jalur file.
• Deklarasikan objek SQLiteDbProvider statis berbasis singleton seperti yang ditentukan di bawah ini:
kelas SQLiteDbProvider
{ SQLiteDbProvider._();
SQLiteDBProvoider.db.<emthod>
• Buat metode untuk mendapatkan database (opsi Masa Depan) dengan tipe Future<Database>.
Buat tabel produk dan muat data awal selama pembuatan database itu sendiri.
initDB() asinkron {
Direktori dokumenDirektori = menunggu
getApplicationDocumentsDirectory(); Jalur string =
gabung(documentsDirectory.path, "ProductDB.db"); kembali menunggu openDatabase( path,
versi: 1,
127
Machine Translated by Google
Berdebar
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[1, "iPhone", "iPhone adalah ponsel penata gaya", 1000,
"iphone.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[2, "Pixel", "Pixel adalah ponsel berfitur terbanyak yang pernah ada", 800,
"piksel.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[3, "Laptop", "Laptop adalah alat pengembangan paling produktif",
2000, "laptop.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[4, "Tablet", "Laptop adalah alat pengembangan paling produktif",
1500, "tablet.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[5, "Flashdisk", "Flashdisk adalah media penyimpanan yang berguna",
100, "Flashdisk.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[6, "Floppy Drive", "Floppy drive adalah media penyimpanan penyelamat
yang berguna", 20, "floppy.png"]); });
128
Machine Translated by Google
Berdebar
• onCreate - Digunakan untuk menulis kode saat database dibuat untuk pertama kali
• db.execute - Digunakan untuk mengeksekusi kueri SQL. Itu menerima kueri. Jika kueri memiliki
mengembalikan produk;
}
• Menggunakan metode kueri untuk mengambil semua informasi produk. kueri menyediakan pintasan untuk
menanyakan informasi tabel tanpa menulis seluruh kueri. metode kueri akan menghasilkan kueri yang tepat
dengan menggunakan input kami seperti kolom, orderBy, dll.,
• Menggunakan metode fromMap Produk untuk mendapatkan detail produk dengan mengulang hasilnya
objek, yang menampung semua baris dalam tabel.
• Di sini, kami telah menggunakan where dan whereArgs untuk menerapkan filter.
• Buat tiga metode - masukkan, perbarui dan hapus metode untuk memasukkan, memperbarui dan menghapus
produk dari database
129
Machine Translated by Google
Berdebar
var id = maxIdResult.first["last_inserted_id"];
mengembalikan hasil;
}
mengembalikan hasil;
}
import 'dart:async';
impor 'panah: io'; impor
'paket: jalur/jalur.dart';
impor 'Produk.dart';
kelas SQLiteDbProvider
{ SQLiteDbProvider._();
initDB() asinkron {
130
Machine Translated by Google
Berdebar
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[1, "iPhone", "iPhone adalah ponsel penata gaya", 1000,
"iphone.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[2, "Pixel", "Pixel adalah ponsel berfitur terbanyak yang pernah ada", 800,
"piksel.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[3, "Laptop", "Laptop adalah alat pengembangan paling produktif",
2000, "laptop.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[4, "Tablet", "Laptop adalah alat pengembangan paling produktif",
1500, "tablet.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[5, "Flashdisk", "Flashdisk adalah media penyimpanan yang berguna",
100, "Flashdisk.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[6, "Floppy Drive", "Floppy drive adalah media penyimpanan penyelamat
yang berguna", 20, "floppy.png"]); });
131
Machine Translated by Google
Berdebar
mengembalikan produk;
}
mengembalikan hasil;
}
mengembalikan hasil;
}
132
Machine Translated by Google
Berdebar
}
}
void main()
{ runApp(MyApp(produk: SQLiteDbProvider.db.getAllProducts()));
}
• Di sini, kami telah menggunakan metode getAllProducts untuk mengambil semua produk dari database.
• Jalankan aplikasi dan lihat hasilnya. Ini akan mirip dengan contoh sebelumnya, Mengakses API layanan
Produk, kecuali informasi produk disimpan dan diambil dari database SQLite lokal.
Flutter menyediakan paket khusus, cloud_firestore untuk memprogram dengan Cloud Firestore. Mari kita
buat toko produk online di Cloud Firestore dan buat aplikasi untuk mengakses toko produk.
kelas Produk
{ nama String akhir;
deskripsi String akhir; harga int
akhir; gambar String akhir;
}
}
• Salin folder aset dari product_rest_app ke product_firebase_app dan tambahkan aset di dalam file
pubspec.yaml
berdebar:
133
Machine Translated by Google
Berdebar
aktiva:
- aset/appimages/floppy.png - aset/
appimages/iphone.png - aset/appimages/
laptop.png - aset/appimages/
pendrive.png - aset/appimages/pixel.png -
aset/appimages/tablet.png
dependensi:
cloud_firestore: ^0.9.13+1
• Android studio akan memberi tahu bahwa pubspec.yaml diperbarui seperti yang ditampilkan di sini:
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan mengonfigurasinya
dengan benar untuk aplikasi tersebut.
https://firebase.google.com/pricing/
• Setelah akun Firebase dibuat, itu akan dialihkan ke halaman ikhtisar proyek. Itu mencantumkan semua
proyek berbasis Firebase dan memberikan opsi untuk membuat proyek baru.
• Klik Tambahkan proyek dan itu akan membuka halaman pembuatan proyek.
• Masukkan db aplikasi produk sebagai nama proyek dan klik opsi Buat proyek.
• Klik ikon android. Ini akan membuka pengaturan proyek khusus untuk pengembangan Android.
• Unduh google_service.json lalu pindahkan ke direktori android/app proyek. File ini adalah koneksi antara
aplikasi kita dan Firebase.
134
Machine Translated by Google
Berdebar
buildscript
{ repositori { // ...
dependencies
{ // ...
classpath 'com.google.gms:google-services:3.2.1' // baru
}
}
Di sini, plugin dan jalur kelas digunakan untuk membaca file google_service.json.
android
{ defaultConfig {
...
multiDexEnabled benar
}
...
}
dependensi {
...
kompilasi 'com.android.support: multidex:1.0.3'
}
• Buat toko produk di proyek yang baru dibuat menggunakan langkah-langkah berikut:
• Klik Tambahkan koleksi. Masukkan produk sebagai nama koleksi, lalu klik Berikutnya.
• Masukkan informasi produk sampel seperti yang ditunjukkan pada gambar di sini:
135
Machine Translated by Google
Berdebar
• Buka file main.dart dan impor file plugin Cloud Firestore dan hapus paket http.
• Hapus parseProducts dan perbarui fetchProducts untuk mengambil produk dari Cloud
Firestore, bukan API layanan Produk
Streaming<QuerySnapshot> fetchProducts() {
return Firestore.instance.collection('product').snapshots();
}
• Di sini, metode Firestore.instance.collection digunakan untuk mengakses koleksi produk yang tersedia di
cloud store. Firestore.instance.collection menyediakan banyak opsi untuk memfilter koleksi untuk mendapatkan
dokumen yang diperlukan. Namun, kami belum menerapkan filter apa pun untuk mendapatkan semua informasi
produk.
• Cloud Firestore menyediakan koleksi melalui konsep Dart Stream sehingga memodifikasi jenis produk di widget MyApp
dan MyHomePage dari Future<list<Product>> menjadi Stream<QuerySnapshot>.
136
Machine Translated by Google
Berdebar
• Ubah metode build widget MyHomePage untuk menggunakan StreamBuilder sebagai gantinya
FutureBuilder.
@mengesampingkan
if (snapshot.hasError) print(snapshot.error);
if(snapshot.hasData)
{ Daftar<DocumentSnapshot> dokumen = snapshot.data.dokumen;
Daftar<Produk> item = Daftar<Produk>();
item.tambahkan(Produk.dariPeta(dokumen.data));
}
} }, ), ));
137
Machine Translated by Google
Saat ini, aplikasi seluler digunakan oleh pelanggan dari berbagai negara dan akibatnya, aplikasi diharuskan menampilkan
konten dalam berbagai bahasa. Mengaktifkan aplikasi untuk bekerja dalam berbagai bahasa disebut Menginternasionalkan
aplikasi.
Agar aplikasi bekerja dalam bahasa yang berbeda, pertama-tama aplikasi harus menemukan lokal saat ini dari sistem
tempat aplikasi berjalan dan kemudian perlu menunjukkan kontennya di lokal tersebut, dan proses ini disebut Lokalisasi.
Framework Flutter menyediakan tiga kelas dasar untuk pelokalan dan kelas utilitas ekstensif yang diturunkan dari kelas
dasar untuk melokalkan aplikasi.
• Lokal - Lokal adalah kelas yang digunakan untuk mengidentifikasi bahasa pengguna. Misalnya, en-us
mengidentifikasi bahasa Inggris Amerika dan dapat dibuat sebagai:
Di sini, argumen pertama adalah kode bahasa dan argumen kedua adalah kode negara.
Contoh lain untuk membuat lokal Argentina Spanyol (es-ar) adalah sebagai berikut:
• Pelokalan - Pelokalan adalah widget generik yang digunakan untuk menyetel Lokal dan sumber daya yang
dilokalkan dari anaknya.
kelas CustomLocalizations
{ CustomLocalizations(this.locale);
}, };
138
Machine Translated by Google
Berdebar
• Di sini, CustomLocalizations adalah kelas khusus baru yang dibuat khusus untuk mendapatkan konten lokal
tertentu (judul dan pesan) untuk widget. metode menggunakan kelas Pelokalan untuk mengembalikan kelas
CustomLocalizations baru.
• LocalizationsDelegate<T> - LocalizationsDelegate<T> adalah kelas pabrik tempat widget Pelokalan dimuat. Ini
memiliki tiga metode over-ridable:
• isSupported - Menerima lokal dan mengembalikan apakah lokal yang ditentukan adalah
didukung atau tidak.
@override
bool isSupported(Locale locale) => ['en',
'es'].contains(locale.languageCode);
• load - Menerima lokal dan mulai memuat sumber daya untuk lokal yang ditentukan.
@mengesampingkan
• shouldReload - Menentukan apakah pemuatan ulang CustomLocalizations diperlukan saat widget Pelokalan
dibuat ulang.
@override
bool shouldReload(CustomLocalizationsDelegate old) => false;
@override
bool didukung(LocalLocal) => ['kami',
'es'].contains(locale.languageCode);
@mengesampingkan
139
Machine Translated by Google
Berdebar
@override
bool shouldReload(CustomLocalizationsDelegate old) => false;
}
Secara umum, aplikasi Flutter didasarkan pada dua widget level root, MaterialApp atau WidgetsApp. Flutter
menyediakan pelokalan siap pakai untuk kedua widget dan keduanya adalah MaterialLocalizations dan
WidgetsLocaliations. Selanjutnya, Flutter juga menyediakan delegasi untuk memuat MaterialLocalizations
dan GlobalMaterialLocalizations.delegate. WidgetsLocaliations dan mereka serta adalah
GlobalWidgetsLocalizations.delegate
Mari kita buat aplikasi berkemampuan internasionalisasi sederhana untuk menguji dan memahami konsepnya.
dependensi:
bergetar:
sdk: bergetar
flutter_localizations: sdk:
bergetar
• Android studio akan menampilkan peringatan berikut bahwa pubspec.yaml telah diperbarui.
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan
mengonfigurasinya dengan benar untuk aplikasi tersebut.
• Di sini, tujuan SynchronousFuture adalah untuk memuat pelokalan khusus secara sinkron.
• Buat pelokalan khusus dan delegasinya yang sesuai seperti yang ditentukan di bawah ini:
kelas CustomLocalizations
{ CustomLocalizations(this.locale);
140
Machine Translated by Google
Berdebar
}, };
@override
bool didukung(LocalLocal) => ['kami',
'es'].contains(locale.languageCode);
@mengesampingkan
@override
bool shouldReload(CustomLocalizationsDelegate old) => false;
}
• Di sini, CustomLocalizations dibuat untuk mendukung pelokalan untuk judul dan pesan dalam aplikasi
dan CustomLocalizationsDelegate digunakan untuk memuat CustomLocalizations.
localizationsDelegate: [ const
CustomLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
SupportLocales: [ const
Locale('en', ''),
141
Machine Translated by Google
Berdebar
• Gunakan metode CustomLocalizations, of untuk mendapatkan nilai judul dan pesan yang dilokalkan
dan gunakan di tempat yang tepat seperti yang ditentukan di bawah ini:
@mengesampingkan
),
body:
Center( anak:
Kolom( mainAxisAlignment: MainAxisAlignment.center,
anak: <Widget>[ Text( CustomLocalizations .of(context)
.pesan, ), ], ), ), );
• Di sini, kami telah memodifikasi kelas MyHomePage dari StatefulWidget menjadi StatelessWidget untuk
alasan kesederhanaan dan menggunakan CustomLocalizations untuk mendapatkan judul dan pesan.
• Mengkompilasi dan menjalankan aplikasi. Aplikasi akan menampilkan kontennya dalam bahasa Inggris.
• Tutup aplikasi. Buka Pengaturan -> Sistem -> Bahasa dan Input ->
Bahasa*
• Klik Tambahkan opsi bahasa dan pilih Spanyol. Ini akan menginstal bahasa Spanyol dan kemudian
mencantumkannya sebagai salah satu opsi.
• Pilih bahasa Spanyol dan pindahkan ke atas bahasa Inggris. Ini akan ditetapkan sebagai bahasa Spanyol sebagai
bahasa pertama dan semuanya akan diubah menjadi teks Spanyol.
• Sekarang luncurkan kembali aplikasi internasionalisasi dan Anda akan melihat judul dan
pesan dalam bahasa spanyol.
• Kita dapat mengembalikan bahasa ke bahasa Inggris dengan memindahkan opsi bahasa Inggris di atas bahasa Spanyol
pilihan dalam pengaturan.
• Hasil aplikasi (dalam bahasa Spanyol) ditunjukkan pada tangkapan layar di bawah ini:
142
Machine Translated by Google
Berdebar
Flutter menyediakan paket intl untuk semakin menyederhanakan pengembangan aplikasi seluler yang
dilokalkan. paket intl menyediakan metode dan alat khusus untuk semi-otomatis menghasilkan pesan khusus
bahasa.
Mari kita buat aplikasi lokal baru dengan menggunakan paket intl dan pahami konsepnya.
dependensi:
bergetar:
sdk: bergetar
flutter_localizations: sdk:
bergetar
intl: ^0.15.7
intl_translation: ^0.17.3
143
Machine Translated by Google
Berdebar
• Android studio akan menampilkan alert seperti dibawah ini yang menginformasikan bahwa pubspec.yaml
diperbarui.
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan
mengonfigurasinya dengan benar untuk aplikasi tersebut.
impor 'paket:intl/intl.dart';
• Perbarui kelas CustomLocalization seperti yang ditunjukkan pada kode di bawah ini:
kelas CustomLocalizations {
masa depan statis<CustomLocalizations> memuat (Lokal lokal) {
nama String akhir = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(nama);
kembali initializeMessages(localeName).kemudian((_) {
Intl.defaultLocale = namalokal; kembalikan
CustomLocalizations(); });
}
}
@mengesampingkan
144
Machine Translated by Google
Berdebar
@ganti
Future<CustomLocalizations> load(Locale locale) { return
CustomLocalizations.load(locale);
}
@override
bool shouldReload(CustomLocalizationsDelegate old) => false;
}
• Di sini, kami telah menggunakan tiga metode dari paket intl alih-alih metode khusus.
Kalau tidak, konsepnya sama.
import 'l10n/messages_all.dart';
• Buka prompt perintah dan buka direktori root aplikasi (di mana pubspec.yaml
tersedia) dan jalankan perintah berikut:
• Di sini, perintah akan menghasilkan, file intl_message.arb, sebuah template untuk membuat pesan di
lokasi yang berbeda. Isi filenya adalah sebagai berikut:
{
"@@last_modified": "2019-04-19T02:04:09.627551", "title":
"Demo", "@title": { "description": "Judul untuk aplikasi Demo",
"type": "text ", "placeholder": {} }, "message": "Halo Dunia",
"@message": {
}
}
• Salin intl_message.arb dan buat file baru, intl_es.arb dan ubah isinya ke bahasa Spanyol seperti yang
ditunjukkan di bawah ini:
145
Machine Translated by Google
Berdebar
{
"@@last_modified": "2019-04-19T02:04:09.627551", "title":
"Manifestación", "@title": { "description": "Judul untuk aplikasi
Demo", "type": "text ", "placeholder": {} }, "message": "Hola
Mundo", "@message": {
}
}
• Sekarang, jalankan perintah berikut untuk membuat file pesan terakhir, messages_all.dart
• Mengkompilasi dan menjalankan aplikasi. Ini akan bekerja mirip dengan aplikasi di atas, flutter_localization_app.
146
Machine Translated by Google
Berdebar
17. Flutter – Pengujian
Pengujian adalah fase yang sangat penting dalam siklus hidup pengembangan aplikasi. Ini memastikan bahwa
aplikasi berkualitas tinggi. Pengujian membutuhkan perencanaan dan pelaksanaan yang cermat. Ini juga
merupakan fase pengembangan yang paling memakan waktu.
Bahasa Dart dan framework Flutter menyediakan dukungan ekstensif untuk pengujian otomatis aplikasi.
Jenis Pengujian
Umumnya, tiga jenis proses pengujian tersedia untuk menguji aplikasi sepenuhnya.
Mereka adalah sebagai berikut:
Pengujian Unit
Pengujian unit adalah metode termudah untuk menguji aplikasi. Ini didasarkan pada memastikan kebenaran
sepotong kode (fungsi, secara umum) atau metode kelas. Tapi, itu tidak mencerminkan lingkungan nyata dan
selanjutnya, adalah pilihan paling sedikit untuk menemukan bug.
Pengujian Widget
Pengujian widget didasarkan pada memastikan kebenaran pembuatan widget, rendering, dan interaksi
dengan widget lain seperti yang diharapkan. Ini melangkah lebih jauh dan menyediakan lingkungan waktu
nyata untuk menemukan lebih banyak bug.
Tes integrasi
Pengujian integrasi melibatkan pengujian unit dan pengujian widget bersama dengan komponen eksternal
aplikasi seperti database, layanan web, dll., Ini mensimulasikan atau mengolok-olok lingkungan nyata untuk
menemukan hampir semua bug, tetapi ini adalah proses yang paling rumit.
Flutter memberikan dukungan untuk semua jenis pengujian. Ini memberikan dukungan ekstensif dan eksklusif
untuk pengujian Widget. Pada bab ini, kita akan membahas pengujian widget secara detail.
Pengujian Widget
Framework pengujian Flutter menyediakan metode testWidgets untuk menguji widget. Itu menerima dua
argumen:
• Deskripsi tes
• Kode uji
147
Machine Translated by Google
Berdebar
Langkah Terlibat
Pengujian Widget melibatkan tiga langkah berbeda:
• WidgetTester adalah kelas yang disediakan oleh framework pengujian Flutter untuk membuat dan merender
widget. metode pumpWidget dari kelas WidgetTester menerima widget apa pun dan merendernya di
lingkungan pengujian.
),
));
});
• Framework Flutter menyediakan banyak opsi untuk menemukan widget yang dirender di lingkungan
pengujian dan umumnya disebut Finder. Pencari yang paling sering digunakan adalah find.text,
find.byKey, dan find.byWidget
• find.text menemukan widget yang berisi teks yang ditentukan.
find.text('Halo')
temukan.byKey('rumah')
temukan.denganWidget(homeWidget)
• Framework Flutter menyediakan banyak opsi untuk mencocokkan widget dengan widget yang diharapkan
dan biasanya disebut Matcher. Kami dapat menggunakan metode ekspektasi yang disediakan oleh
kerangka pengujian untuk mencocokkan widget, yang kami temukan di langkah kedua dengan widget
yang kami harapkan dengan memilih salah satu pencocokan. Beberapa pencocokan penting adalah
sebagai berikut:
mengharapkan(menemukan.teks('Halo'), menemukanSatuWidget);
148
Machine Translated by Google
Berdebar
mengharapkan(menemukan.teks('Simpan'), menemukanWidgets);
mengharapkan(menemukan.teks('Simpan'), menemukanNWidgets(2));
),
));
mengharapkan(menemukan.teks('Halo'), menemukanSatuWidget);
});
Di sini, kami merender widget MaterialApp dengan teks Halo menggunakan widget Teks di badannya.
Kemudian, kami menggunakan find.text untuk menemukan widget dan kemudian mencocokkannya menggunakan foundOneWidget.
Contoh Kerja
Mari kita membuat aplikasi bergetar sederhana dan menulis tes widget untuk lebih memahami langkah-langkah yang
terlibat dan konsepnya.
• Buka widget_test.dart di folder test. Ini memiliki kode pengujian sampel seperti yang diberikan di bawah ini:
• Memastikan bahwa penghitung awalnya nol menggunakan menemukanSatuWidget dan menemukanTidak ada
pertandingan.
149
Machine Translated by Google
Berdebar
• Mari kita ketuk lagi tombol kenaikan penghitung dan kemudian periksa apakah penghitung dinaikkan
menjadi dua.
mengharapkan(menemukan.teks('2'), menemukanSatuWidget);
• Klik tes di opsi widget_test.dart. Ini akan menjalankan pengujian dan melaporkan hasilnya di jendela
hasil.
150
Machine Translated by Google
Bab ini menjelaskan cara menerapkan aplikasi Flutter di platform Android dan iOS.
Aplikasi Android
• Ubah nama aplikasi menggunakan entri android:label di file manifes android.
File manifes aplikasi Android, AndroidManifest.xml terletak di <app dir>/android/app/src/main. Ini berisi
seluruh detail tentang aplikasi android.
Kita dapat mengatur nama aplikasi menggunakan entri android:label.
cd /path/to/my/application flutter
build apk
instalasi bergetar
Aplikasi iOS
• Daftarkan aplikasi iOS di App Store Connect menggunakan metode standar. Simpan =Bundle ID yang
digunakan saat mendaftar aplikasi.
• Perbarui nama Tampilan dalam pengaturan proyek XCode untuk mengatur nama aplikasi.
151
Machine Translated by Google
Berdebar
• Perbarui Pengidentifikasi Bundel dalam pengaturan proyek XCode untuk mengatur id bundel, yang kami
digunakan pada langkah 1.
......................
• Uji aplikasi dengan mendorong aplikasi, file IPA ke dalam TestFlight menggunakan metode
standar.
152
Machine Translated by Google
Bab ini menjelaskan tentang alat pengembangan Flutter secara mendetail. Rilis stabil pertama dari toolkit pengembangan
lintas platform dirilis pada 4 Desember 2018, Flutter 1.0.
Yah, Google terus berupaya meningkatkan dan memperkuat kerangka kerja Flutter dengan berbagai alat pengembangan.
Set Widget
Google memperbarui untuk set widget Material dan Cupertino untuk memberikan kualitas piksel sempurna dalam desain
komponen. Versi mendatang dari flutter 1.2 akan dirancang untuk mendukung event keyboard desktop dan dukungan
mouse hover.
• Bantuan kode - Saat Anda ingin memeriksa opsi, Anda dapat menggunakan Ctrl+Spasi untuk mendapatkan a
daftar opsi penyelesaian kode.
• Perbaikan cepat - Ctrl+. adalah alat perbaikan cepat untuk membantu memperbaiki kode.
• Men-debug pintasan.
• Hot restart
Dart DevTools
Kita dapat menggunakan Android Studio atau Visual Studio Code, atau IDE lainnya untuk menulis kode kita dan
memasang plugin. Tim pengembangan Google sedang mengerjakan alat pengembangan lain yang disebut Dart DevTools
Ini adalah rangkaian pemrograman berbasis web. Ini mendukung platform Android dan iOS. Ini didasarkan pada tampilan
garis waktu sehingga pengembang dapat dengan mudah menganalisis aplikasi mereka.
Instal DevTools
Untuk menginstal DevTools, jalankan perintah berikut di konsol Anda:
153
Machine Translated by Google
Berdebar
+ charcode 1.1.2 +
codemirror 0.5.3+5.44.0
+ koleksi 1.14.11
+ konversi 2.1.1 +
devtools 0.0.16
+ devtools_server 0.0.2 + http
0.12.0+2 + http_parser 3.1.3
+ intl 0.15.8
+ js 0.6.1+1 +
target 1.1.7
+ pantomim 0.9.6+2
.................
.................
Jalankan Server
http://localhost:9100/?port=9200
154
Machine Translated by Google
Berdebar
Berkibar SDK
Untuk memperbarui Flutter SDK, gunakan perintah berikut:
peningkatan bergetar
Inspektur Flutter
Ini digunakan untuk menjelajahi pohon widget flutter. Untuk mencapai ini, jalankan perintah di bawah ini di
konsol Anda,
155
Machine Translated by Google
Berdebar
2.904 md (!)
Untuk memuat ulang perubahan saat menjalankan, tekan "r". Untuk hot restart (dan membangun kembali status),
tekan "R".
Debugger Observatory dan profiler di iPhone X tersedia di: http://127.0.0.1:50399/ Untuk pesan
bantuan yang lebih mendetail, tekan "h". Untuk melepaskan, tekan "d"; untuk keluar, tekan "q".
156
Machine Translated by Google
Dalam bab ini, kita akan mempelajari cara menulis aplikasi seluler lengkap, kalkulator_pengeluaran. Tujuan
dari kalkulator_pengeluaran adalah untuk menyimpan informasi pengeluaran kita. Fitur lengkap dari aplikasi ini
adalah sebagai berikut:
• Daftar biaya
• Formulir untuk memasukkan biaya baru
• Pilihan untuk mengedit/menghapus pengeluaran yang ada
• Total pengeluaran kapan saja.
Kita akan memprogram aplikasi expense_calculator menggunakan fitur-fitur canggih kerangka kerja Flutter
yang disebutkan di bawah.
• Pemrograman bentuk
• Pemrograman basis data SQLite untuk menyimpan pengeluaran kita
• manajemen keadaan scoped_model untuk menyederhanakan pemrograman kita.
dependensi:
bergetar:
sdk: bergetar
sqflite: ^1.1.0
path_provider: ^0.5.0+1
scoped_model: ^1.0.1 intl: apa
saja
• Android studio akan menampilkan peringatan berikut bahwa pubspec.yaml telah diperbarui.
• Klik opsi Dapatkan dependensi. Studio Android akan mendapatkan paket dari Internet dan
mengonfigurasinya dengan benar untuk aplikasi tersebut.
157
Machine Translated by Google
Berdebar
• Tambahkan file baru, Expense.dart untuk membuat kelas Expense. Kelas biaya akan memiliki properti dan
metode di bawah ini.
);
}
• toMap - Digunakan untuk mengonversi objek pengeluaran menjadi Dart Map, yang selanjutnya dapat
digunakan dalam pemrograman basis data
• kolom - Variabel statis yang digunakan untuk mewakili bidang basis data.
impor 'paket:intl/intl.dart';
kelas Pengeluaran
{ final int id;
jumlah ganda akhir;
tanggal DateTime akhir;
kategori String terakhir;
158
Machine Translated by Google
Berdebar
DateTime.parse(data['date']),
data['category'] );
• Tambahkan file baru, Database.dart untuk membuat kelas SQLiteDbProvider. Tujuan kelas SQLiteDbProvider
adalah sebagai berikut:
• Dapatkan semua biaya yang tersedia di database menggunakan metode getAllExpenses. Dia
akan digunakan untuk mencantumkan semua informasi pengeluaran pengguna.
biaya pengembalian;
}
• Dapatkan informasi pengeluaran khusus berdasarkan identitas pengeluaran yang tersedia di database
menggunakan metode getExpenseById. Ini akan digunakan untuk menunjukkan informasi
pengeluaran tertentu kepada pengguna.
159
Machine Translated by Google
Berdebar
• Menambahkan informasi pengeluaran baru ke dalam database menggunakan metode insert. Itu akan
digunakan untuk menambahkan entri biaya baru ke dalam aplikasi oleh pengguna.
• Perbarui informasi pengeluaran yang ada menggunakan metode pembaruan. Ini akan digunakan untuk
mengedit dan memperbarui entri pengeluaran yang ada yang tersedia di sistem oleh pengguna.
mengembalikan hasil;
}
• Hapus informasi pengeluaran yang ada menggunakan metode hapus. Ini akan digunakan untuk
menghapus entri pengeluaran yang tersedia di sistem oleh pengguna.
160
Machine Translated by Google
Berdebar
impor 'Biaya.dart';
kelas SQLiteDbProvider
{ SQLiteDbProvider._();
initDB() asinkron {
Direktori dokumenDirektori = menunggu getApplicationDocumentsDirectory(); Jalur string =
gabung(documentsDirectory.path, "ExpenseDB2.db"); kembali menunggu openDatabase( path,
versi: 1, onOpen: (db) {}, onCreate: (Database db, versi int) async {
await
db.execute( "INSERT INTO Expense ('id', 'amount', 'date', 'category') nilai (?, ?, ?, ?)",
[1, 1000, '2019-04-01 10 :00:00', "Makanan"]);
/*await
db.execute( "INSERT INTO Product ('id', 'name', 'description', 'price',
'gambar') nilai (?, ?, ?, ?, ?)",
[2, "Pixel", "Pixel adalah ponsel berfitur terbanyak yang pernah ada", 800,
161
Machine Translated by Google
Berdebar
"piksel.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[3, "Laptop", "Laptop adalah alat pengembangan paling produktif", 2000, "laptop.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[4, "Tablet", "Laptop adalah alat pengembangan paling produktif", 1500, "tablet.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[5, "Flashdisk", "iPhone adalah ponsel penata gaya", 100,
"pendrive.png"]);
await
db.execute( "MASUKKAN KE PRODUK ('id', 'nama', 'deskripsi', 'harga',
'gambar') nilai (?, ?, ?, ?, ?)",
[6, "Floppy Drive", "iPhone adalah ponsel stylist yang pernah ada", 20,
"floppy.png"]); */ });
biaya pengembalian;
}
162
Machine Translated by Google
Berdebar
mengembalikan hasil;
}
• Di Sini,
• Buat file baru, ExpenseListModel.dart untuk membuat ExpenseListModel. Tujuan dari model ini adalah untuk
menyimpan informasi lengkap tentang pengeluaran pengguna dalam memori dan memperbarui antarmuka
pengguna aplikasi setiap kali pengeluaran pengguna berubah dalam memori. Ini didasarkan pada kelas
Model dari paket scoped_model. Ini memiliki properti dan metode berikut:
163
Machine Translated by Google
Berdebar
jumlah pengembalian;
}
• load - Digunakan untuk memuat pengeluaran lengkap dari database dan ke dalam variabel
_items. Itu juga memanggil notifyListeners untuk memperbarui UI.
void load()
{ Future<List<Expense>> list = SQLiteDbProvider.db.getAllExpenses();
notifyListeners(); });
Pengeluaran menurutId(int
id) { for(var i = 0; i < _items.length; i++) { if(_items[i].id
== id) { return _items[i];
}
}
kembali nol;
}
• add - Digunakan untuk menambahkan item pengeluaran baru ke dalam variabel _items dan juga
ke dalam database. Itu juga memanggil notifyListeners untuk memperbarui UI.
notifyListeners(); });
• add - Digunakan untuk menambahkan item pengeluaran baru ke dalam variabel _items dan juga ke
dalam database. Itu juga memanggil notifyListeners untuk memperbarui UI.
164
Machine Translated by Google
Berdebar
}
}
jika(ditemukan) notifyListeners();
}
• hapus - Digunakan untuk menghapus item pengeluaran yang ada di variabel _items juga
dari basis data. Itu juga memanggil notifyListeners untuk memperbarui UI.
}
}
jika(ditemukan) notifyListeners();
}
ExpenseListModel() { this.load(); }
165
Machine Translated by Google
Berdebar
jumlah pengembalian;
}
void load()
{ Future<List<Expense>> list =
SQLiteDbProvider.db.getAllExpenses();
notifyListeners(); });
Pengeluaran menurutId(int
id) { for(var i = 0; i < _items.length; i++)
{ if(_items[i].id == id) { return _items[i];
}
}
kembali nol;
}
notifyListeners(); });
}
}
jika(ditemukan) notifyListeners();
}
166
Machine Translated by Google
Berdebar
}
}
jika(ditemukan) notifyListeners();
}
}
• Buka file main.dart. Impor kelas seperti yang ditentukan di bawah ini:
impor 'Biaya.dart';
void main()
{ biaya akhir = ExpenseListModel();
runApp(ScopedModel<ExpenseListModel>( model:
pengeluaran, anak: MyApp(), ));
• Di Sini,
• ScopedModel memberikan informasi biaya selama seluruh siklus hidup aplikasi dan memastikan
pemeliharaan status aplikasi kapan saja. Ini memungkinkan kita untuk menggunakan
StatelessWidget alih-alih StatefulWidget.
kembalikan
MaterialApp( judul:
'Biaya', tema: ThemeData(
167
Machine Translated by Google
Berdebar
}
}
• Buat widget MyHomePage untuk menampilkan semua informasi pengeluaran pengguna beserta total
pengeluaran di bagian atas. Tombol floating di pojok kanan bawah akan digunakan untuk menambah
pengeluaran baru.
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title: Text(this.title), ),
body:
ScopedModelDescendant<ExpenseListModel>( builder:
(konteks, anak, pengeluaran) { return ListView.separated(
); } else
{ indeks = indeks - 1;
return Dismissible( key:
Key(expenses.items[index].id.toString()), onDismissed:
(direction) {
pengeluaran.hapus(pengeluaran.item[indeks]);
Scaffold.of(konteks).showSnackBar(SnackBar( konten:
Teks("Item dengan id, " +
pengeluaran.item[indeks].id.toString()
+
" diberhentikan")));
},
anak: ListTile( onTap:
()
{ Navigator.push( konteks,
MaterialPageRoute( pembangun: (konteks)
=> FormPage( id:
pengeluaran.item[indeks].id,
168
Machine Translated by Google
Berdebar
pengeluaran:
pengeluaran, )));
},
memimpin: Ikon(Icons.monetization_on), mengikuti:
Ikon(Icons.keyboard_arrow_right),
title: Text(expenses.items[index].category
+
":" +
Navigator.push( konteks,
MaterialPageRoute( pembangun:
(konteks) => ScopedModelDescendant<ExpenseListModel>(
pembangun: (konteks, turunan, pengeluaran)
{ return FormPage( id: 0,
pengeluaran:
pengeluaran, ); }))); //
pengeluaran.tambahkan(Pengeluaran
baru( 2, 1000, DateTime.parse('2019-04-01
11:00:00'), //
'Makanan'));
// cetak(pengeluaran.barang.panjang); },
keterangan alat: 'Kenaikan', anak:
Ikon(Ikon.tambahkan), ); }));
}
}
• Di Sini,
169
Machine Translated by Google
Berdebar
• Widget ListView.separated dan ListTile digunakan untuk membuat daftar informasi pengeluaran.
• Widget yang dapat ditutup digunakan untuk menghapus entri pengeluaran menggunakan gerakan menggesek.
• Navigator digunakan untuk membuka antarmuka edit entri pengeluaran. Ini dapat diaktifkan oleh
mengetuk entri pengeluaran.
• Membuat widget FormPage. Tujuan widget FormPage adalah untuk menambah atau memperbarui entri
pengeluaran. Ini menangani validasi entri biaya juga.
@mengesampingkan
jumlah_ganda;
DateTime _date;
String _kategori;
batal _kirim() {
bentuk akhir = formKey.currentState;
if (form.validate())
{ form.save();
jika (ini.id == 0)
pengeluaran.tambahkan(Pengeluaran(0, _jumlah, _tanggal,
_kategori)); lainnya pengeluaran.update(Pengeluaran(ini.id, _jumlah,
_tanggal, _kategori));
Navigator.pop(konteks);
}
}
@mengesampingkan
170
Machine Translated by Google
Berdebar
),
body:
Padding( padding: const EdgeInsets.all(16.0),
anak: Form( kunci: formKey, anak: Kolom( anak:
[ TextFormField( style: TextStyle(fontSize:
22), dekorasi: const InputDecoration( icon:
const Ikon(Icons.monetization_on),
labelText: 'Jumlah', labelStyle:
TextStyle(fontSize:
18)),
validator: (val) {
pola pola = r'^[1-9]\d*(\.\d+)?$'; RegExp regex = new
RegExp(pola); if (!regex.hasMatch(val)) return
'Masukkan nomor yang valid'; kalau tidak
kembali nol;
},
Nilai awal:
id == 0 ? '' : pengeluaran.byId(id).amount.toString(), onSaved:
(val) => _amount = double.parse(val), ), TextFormField( style:
TextStyle(fontSize: 22), dekorasi: const InputDecoration(
},
onSaved: (val) => _date = DateTime.parse(val), initialValue:
id == 0 ? '' pengeluaran.byId(id).formattedDate,
: keyboardType:
TextInputType.datetime, ), TextFormField( style: TextStyle(fontSize: 22), dekorasi:
const InputDecoration( icon: const Icon(Icons.category),
labelText:
: pengeluaran.byId(id).category.toString(),
171
Machine Translated by Google
Berdebar
),
RaisedButton( onPressed:
_kirim, anak: Teks
baru('Kirim'), ), ], ), ), ), );
}
}
• Di Sini,
• properti validator dari TextFormField digunakan untuk memvalidasi elemen form bersama dengan
Pola RegEx.
• Fungsi _submit digunakan bersama dengan objek pengeluaran untuk menambah atau memperbarui
pengeluaran ke dalam database.
impor 'Biaya.dart';
batal main() {
pengeluaran akhir = ExpenseListModel();
runApp(ScopedModel<ExpenseListModel>( model:
pengeluaran, anak: MyApp(), ));
ThemeData( primarySwatch:
Colors.blue, ), home: MyHomePage(title:
'Expense calculator'), );
}
}
172
Machine Translated by Google
Berdebar
@override
Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title: Text(this.title), ),
body:
ScopedModelDescendant<ExpenseListModel>( builder:
(konteks, anak, pengeluaran) { return ListView.separated(
); } else
{ indeks = indeks - 1;
return Dismissible( key:
Key(expenses.items[index].id.toString()), onDismissed:
(direction) {
pengeluaran.hapus(pengeluaran.item[indeks]);
Scaffold.of(konteks).showSnackBar(SnackBar( konten:
Teks("Item dengan id, " +
pengeluaran.item[indeks].id.toString() + "
diberhentikan")));
},
anak: ListTile( onTap:
()
{ Navigator.push( konteks,
MaterialPageRoute( pembangun: (konteks) => FormPage(
id: biaya.item[indeks].id,
pengeluaran:
pengeluaran, )));
},
memimpin: Ikon(Icons.monetization_on), mengikuti:
Ikon(Icons.keyboard_arrow_right), judul:
Teks(pengeluaran.item[indeks].kategori +
": " +
pengeluaran.item[indeks].amount.toString() + " \nsbelanja
" +
pengeluaran.item[indeks].formattedDate, gaya:
} },
separatorBuilder: (konteks, indeks) {
173
Machine Translated by Google
Berdebar
kembali
Pembagi(); }, ); }, ),
floatingActionButton:
Navigator.push( konteks,
MaterialPageRoute( pembangun: (konteks) =>
ScopedModelDescendant<ExpenseListModel>( pembangun:
(konteks, turunan, pengeluaran) { return
FormPage( id: 0,
pengeluaran:
pengeluaran, ); }))); //
pengeluaran.tambahkan(Pengeluaran baru( //
2, 1000,11:00:00'),
DateTime.parse('2019-04-01
'Makanan'));
// cetak(pengeluaran.barang.panjang); },
keterangan alat: 'Kenaikan', anak:
Ikon(Ikon.tambahkan), ); }));
}
}
@mengesampingkan
jumlah_ganda;
DateTime _date;
String _kategori;
174
Machine Translated by Google
Berdebar
batal _kirim() {
bentuk akhir = formKey.currentState;
if (form.validate())
{ form.save();
jika (ini.id == 0)
pengeluaran.tambahkan(Pengeluaran(0, _jumlah, _tanggal,
_kategori)); lainnya pengeluaran.update(Pengeluaran(ini.id, _jumlah,
_tanggal, _kategori));
Navigator.pop(konteks);
}
}
@mengesampingkan
18)),
validator: (val) {
pola pola = r'^[1-9]\d*(\.\d+)?$'; RegExp regex = new
RegExp(pola); if (!regex.hasMatch(val)) return
'Masukkan nomor yang valid'; kalau tidak
kembali nol;
},
Nilai awal:
id == 0 ? '' : pengeluaran.byId(id).amount.toString(), onSaved:
(val) => _amount = double.parse(val), ), TextFormField( style:
TextStyle(fontSize: 22), dekorasi: const InputDecoration(
175
Machine Translated by Google
Berdebar
},
onSaved: (val) => _date = DateTime.parse(val), initialValue:
id == 0 ? '' pengeluaran.byId(id).formattedDate,
: keyboardType:
TextInputType.datetime, ), TextFormField( style: TextStyle(fontSize: 22), dekorasi:
const InputDecoration( icon: const Icon(Icons.category),
labelText:
: pengeluaran.byId(id).category.toString(),
),
RaisedButton( onPressed:
_kirim, anak: Teks
baru('Kirim'), ), ], ), ), ), );
}
}
• Hapus pengeluaran yang ada dengan menggeser entri pengeluaran ke salah satu arah.
176
Machine Translated by Google
Berdebar
177
Machine Translated by Google
Berdebar
178
Machine Translated by Google
Berdebar
179
Machine Translated by Google
Kerangka kerja Flutter melakukan pekerjaan yang hebat dengan menyediakan kerangka kerja yang sangat baik untuk
membangun aplikasi seluler dengan cara yang benar-benar mandiri platform. Dengan memberikan kemudahan dalam proses
pengembangan, kinerja tinggi dalam aplikasi seluler yang dihasilkan, antarmuka pengguna yang kaya dan relevan untuk platform
Android dan iOS, framework Flutter pasti akan memungkinkan banyak pengembang baru untuk mengembangkan aplikasi seluler
berkinerja tinggi dan penuh fitur di tidak lama lagi.
180