Flutter - Panduan Cepat

Secara umum, mengembangkan aplikasi seluler adalah tugas yang kompleks dan menantang. Ada banyak kerangka kerja yang tersedia untuk mengembangkan aplikasi seluler. Android menyediakan framework native berdasarkan bahasa Java dan iOS menyediakan framework native berdasarkan bahasa Objective-C / Swift.

Namun, untuk mengembangkan aplikasi yang mendukung kedua OS tersebut, kita perlu membuat kode dalam dua bahasa berbeda menggunakan dua kerangka kerja yang berbeda. Untuk membantu mengatasi kerumitan ini, terdapat kerangka kerja seluler yang mendukung kedua OS tersebut. Kerangka kerja ini berkisar dari kerangka kerja aplikasi seluler hibrid berbasis HTML sederhana (yang menggunakan HTML untuk Antarmuka Pengguna dan JavaScript untuk logika aplikasi) hingga kerangka kerja khusus bahasa yang kompleks (yang melakukan tugas berat untuk mengonversi kode ke kode asli). Terlepas dari kesederhanaan atau kerumitannya, framework ini selalu memiliki banyak kelemahan, salah satu kelemahan utamanya adalah kinerjanya yang lambat.

Dalam skenario ini, Flutter - framework sederhana dan berperforma tinggi berdasarkan bahasa Dart, memberikan performa tinggi dengan merender UI langsung di kanvas sistem operasi, bukan melalui framework asli.

Flutter juga menawarkan banyak widget (UI) siap pakai 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 dapat memiliki status opsional. 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.

Kami akan membahas arsitektur lengkap dalam bab-bab selanjutnya.

Fitur Flutter

Kerangka kerja Flutter menawarkan fitur-fitur berikut kepada pengembang -

  • Kerangka modern dan reaktif.

  • Menggunakan bahasa pemrograman Dart dan sangat mudah dipelajari.

  • Perkembangan cepat.

  • Antarmuka pengguna yang indah dan lancar.

  • Katalog widget besar.

  • Menjalankan UI yang sama untuk berbagai platform.

  • Aplikasi berkinerja tinggi.

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 -

  • Dart memiliki gudang besar paket perangkat lunak 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 satu kali untuk kedua platform.

  • Kesederhanaan Flutter menjadikannya kandidat yang baik untuk pengembangan cepat. Kemampuan penyesuaian dan perpanjangannya membuatnya semakin bertenaga.

  • Dengan Flutter, pengembang memiliki kendali penuh atas widget dan tata letaknya.

  • Flutter menawarkan alat pengembang yang hebat, dengan hot reload yang luar biasa.

Kekurangan Flutter

Terlepas dari banyak keuntungannya, flutter memiliki kekurangan sebagai berikut -

  • Karena dikodekan dalam bahasa Dart, pengembang perlu mempelajari bahasa baru (meskipun mudah dipelajari).

  • Kerangka kerja modern mencoba memisahkan logika dan UI sebanyak mungkin, tetapi di Flutter, antarmuka pengguna dan logika saling bercampur. Kita bisa mengatasi ini dengan menggunakan smart coding dan menggunakan modul tingkat tinggi untuk memisahkan antarmuka pengguna dan logika.

  • Flutter adalah kerangka kerja lain untuk membuat aplikasi seluler. Pengembang mengalami kesulitan dalam memilih alat pengembangan yang tepat di segmen yang sangat padat.

Bab ini akan memandu Anda melalui penginstalan Flutter di komputer lokal Anda secara detail.

Instalasi di Windows

Di bagian ini, mari kita lihat cara menginstal Flutter SDK dan persyaratannya di sistem windows.

Step 1 - Buka URL,https://flutter.dev/docs/get-started/install/windowsdan unduh Flutter SDK terbaru. Pada April 2019, versinya adalah 1.2.1 dan filenya adalah flutter_windows_v1.2.1-stable.zip.

Step 2 - Buka zip arsip zip di folder, katakan C: \ flutter \

Step 3 - Perbarui jalur sistem untuk menyertakan direktori flutter bin.

Step 4 - Flutter menyediakan alat, dokter flutter untuk memeriksa bahwa semua persyaratan pengembangan flutter terpenuhi.

flutter doctor

Step 5 - Menjalankan perintah di atas akan menganalisis sistem dan menampilkan laporannya seperti yang ditunjukkan di bawah ini -

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.2.1, on Microsoft Windows [Version
10.0.17134.706], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version
28.0.3)
[√] Android Studio (version 3.2)
[√] VS Code, 64-bit edition (version 1.29.1)
[!] Connected device
! No devices available
! Doctor found issues in 1 category.

Laporan tersebut mengatakan bahwa semua alat pengembangan tersedia tetapi perangkat tidak terhubung. Kami dapat memperbaikinya dengan menghubungkan perangkat android melalui USB atau memulai emulator android.

Step 6 - Instal SDK Android terbaru, jika dilaporkan oleh flutter doctor

Step 7 - Instal Android Studio terbaru, jika dilaporkan oleh flutter doctor

Step 8 - Mulai emulator android atau hubungkan perangkat android asli ke sistem.

Step 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.,

  • Buka Android Studio.

  • Klik File → Settings → Plugins.

  • Pilih plugin Flutter dan klik Pasang.

  • Klik Yes saat diminta untuk menginstal plugin Dart.

  • Mulai ulang studio Android.

Instalasi di MacOS

Untuk menginstal Flutter di MacOS, Anda harus mengikuti langkah-langkah berikut -

Step 1 - Buka URL,https://flutter.dev/docs/get-started/install/macosdan unduh Flutter SDK terbaru. Pada April 2019, versinya adalah 1.2.1 dan file adalah flutter_macos_v1.2.1- stable.zip.

Step 2 - Buka zip arsip zip di folder, katakan / path / to / flutter

Step 3 - Perbarui jalur sistem untuk menyertakan direktori flutter bin (dalam file ~ / .bashrc).

> export PATH = "$PATH:/path/to/flutter/bin"

Step 4 - Aktifkan jalur yang diperbarui di sesi saat ini menggunakan perintah di bawah ini dan kemudian verifikasi juga.

source ~/.bashrc
source $HOME/.bash_profile
echo $PATH

Flutter menyediakan alat, dokter flutter untuk memeriksa bahwa semua persyaratan pengembangan flutter terpenuhi. Ini mirip dengan mitra Windows.

Step 5 - Instal Xcode terbaru, jika dilaporkan oleh flutter doctor

Step 6 - Instal SDK Android terbaru, jika dilaporkan oleh flutter doctor

Step 7 - Instal Android Studio terbaru, jika dilaporkan oleh flutter doctor

Step 8 - Mulai emulator android atau hubungkan perangkat android asli ke sistem untuk mengembangkan aplikasi android.

Step 9 - Buka simulator iOS atau hubungkan perangkat iPhone asli ke sistem untuk mengembangkan aplikasi iOS.

Step 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.,

  • Buka Android Studio

  • Klik Preferences → Plugins

  • Pilih plugin Flutter dan klik Pasang

  • Klik Yes saat diminta untuk menginstal plugin Dart.

  • Mulai ulang studio Android.

Di bab ini, mari kita buat aplikasi Flutter sederhana untuk memahami dasar-dasar pembuatan aplikasi flutter di Android Studio.

Step 1 - Buka Android Studio

Step 2- Buat Proyek Flutter. Untuk ini, klikFile → New → New Flutter Project

Step 3- Pilih Aplikasi Flutter. Untuk ini, pilihFlutter Application dan klik Next.

Step 4 - Konfigurasi aplikasi seperti di bawah ini dan klik Next.

  • Nama Proyek: hello_app

  • Jalur SDK Flutter: <path_to_flutter_sdk>

  • Lokasi proyek: <path_to_project_folder>

  • Deskripsi: Flutter based hello world application

Step 5 - Konfigurasi Proyek.

Tetapkan domain perusahaan sebagai flutterapp.tutorialspoint.com dan klik Finish.

Step 6 - Masukkan domain Perusahaan.

Android Studio membuat aplikasi flutter yang berfungsi penuh dengan fungsionalitas minimal. Mari kita periksa struktur aplikasi dan kemudian ubah kode untuk melakukan tugas kita.

Struktur aplikasi dan tujuannya adalah sebagai berikut -

Berbagai komponen struktur aplikasi dijelaskan di sini -

  • android - Kode sumber yang dibuat secara otomatis untuk membuat aplikasi android

  • ios - Kode sumber yang dibuat secara otomatis untuk membuat aplikasi ios

  • lib - Folder utama berisi kode Dart yang ditulis dengan menggunakan flutter framework

  • ib/main.dart - Titik masuk aplikasi Flutter

  • test - Folder yang berisi kode Dart untuk menguji aplikasi flutter

  • test/widget_test.dart - Kode sampel

  • .gitignore - File kontrol versi Git

  • .metadata - dihasilkan secara otomatis oleh alat flutter

  • .packages - dibuat secara otomatis untuk melacak paket flutter

  • .iml - file proyek yang digunakan oleh studio Android

  • pubspec.yaml - Digunakan oleh Pub, Manajer paket Flutter

  • pubspec.lock - Dibuat secara otomatis oleh pengelola paket Flutter, Pub

  • README.md - File deskripsi proyek ditulis dalam format penurunan harga

Step 7- Ganti kode dart di file lib / main.dart dengan kode di bawah ini -

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
   // This widget is the root of your application.
   @override
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Hello World Demo Application',
         theme: ThemeData(
            primarySwatch: Colors.blue,
         ),
         home: MyHomePage(title: 'Home page'),
      );
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;

   @override
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title),
         ),
         body: Center(
            child:
            Text(
               'Hello World',
            )
         ),
      );
   }
}

Mari kita pahami kode panah baris demi baris.

  • Line 1- mengimpor paket flutter, material . Materi adalah paket flutter untuk membuat antarmuka pengguna sesuai dengan pedoman desain Material yang ditentukan oleh Android.

  • Line 3- Ini adalah titik masuk aplikasi Flutter. Memanggil fungsi runApp dan meneruskannya ke objek kelas MyApp . Tujuan dari fungsi runApp adalah untuk memasang widget yang diberikan ke layar.

  • Line 5-17- Widget digunakan untuk membuat UI dalam kerangka flutter. StatelessWidget adalah widget, yang tidak mempertahankan status widget apa pun. MyApp memperluas StatelessWidget dan mengganti metode pembuatannya . Tujuan dari metode build adalah membuat bagian UI aplikasi. Di sini, metode build menggunakan MaterialApp , sebuah widget untuk membuat UI level root aplikasi. Ini memiliki tiga properti - judul, tema, dan rumah .

    • judul adalah judul aplikasi

    • theme adalah tema widget. Di sini, kami menetapkan biru sebagai warna keseluruhan aplikasi menggunakan kelas ThemeData dan propertinya, primarySwatch .

    • home adalah UI bagian dalam aplikasi, yang kami setel widget lain, MyHomePage

  • Line 19 - 38- MyHomePage sama dengan MyApp kecuali ia mengembalikan Scaffold Widget. Scaffold adalah widget level atas di samping widget MaterialApp yang digunakan untuk membuat desain material yang sesuai dengan UI. Ini memiliki dua properti penting, appBar untuk menampilkan header aplikasi dan body untuk menampilkan konten aplikasi yang sebenarnya. AppBar adalah widget lain untuk merender header aplikasi dan kami telah menggunakannya di properti appBar . Di properti body , kami telah menggunakan widget Center , yang memusatkannya widget anak. Teks adalah widget paling akhir dan paling dalam untuk menampilkan teks dan ditampilkan di tengah layar.

Step 8 - Sekarang, jalankan aplikasinya menggunakan, Run → Run main.dart

Step 9 - Terakhir, keluaran dari aplikasi ini adalah sebagai berikut -

Dalam bab ini, mari kita bahas arsitektur framework Flutter.

Widget

Konsep inti dari kerangka Flutter adalah In Flutter, Everything is a widget. Widget pada dasarnya adalah komponen antarmuka pengguna yang digunakan untuk membuat antarmuka pengguna aplikasi.

Di Flutter , aplikasi itu sendiri adalah widget. Aplikasi tersebut adalah widget level atas dan UI-nya dibangun menggunakan satu atau lebih turunan (widget), yang sekali lagi dibuat menggunakan widget turunannya. Inicomposability fitur membantu kami membuat antarmuka pengguna dengan kerumitan apa pun.

Misalnya, hierarki widget aplikasi hello world (dibuat di bab sebelumnya) seperti yang ditentukan dalam diagram berikut -

Di sini poin-poin berikut ini patut diperhatikan -

  • MyApp adalah widget yang dibuat oleh pengguna dan dibuat menggunakan widget asli Flutter, MaterialApp .

  • MaterialApp memiliki properti rumah untuk menentukan antarmuka pengguna dari halaman beranda, yang juga merupakan widget yang dibuat pengguna, MyHomePage .

  • MyHomePage dibuat menggunakan widget asli flutter lainnya, Scaffold

  • Scaffold memiliki dua properti - body dan appBar

  • body digunakan untuk menentukan antarmuka pengguna utamanya dan appBar digunakan untuk menentukan antarmuka pengguna tajuknya

  • Header UI dibuat menggunakan widget asli flutter, AppBar dan Body UI dibuat menggunakan widget Center .

  • The Pusat widget memiliki properti, Anak , yang mengacu konten yang sebenarnya dan itu adalah membangun menggunakan Text widget

Gestur

Widget Flutter mendukung interaksi melalui widget khusus, GestureDetector . GestureDetector adalah widget tak terlihat yang memiliki kemampuan untuk menangkap interaksi pengguna seperti mengetuk, menyeret, dll., Dari widget turunannya. Banyak widget asli Flutter mendukung interaksi melalui penggunaan GestureDetector . Kami juga dapat memasukkan fitur interaktif ke dalam widget yang sudah ada dengan menyusunnya menggunakan widget GestureDetector . Kita akan mempelajari gerakan secara terpisah di bab-bab selanjutnya.

Konsep Negara

Widget Flutter mendukung pemeliharaan Status dengan menyediakan widget khusus, StatefulWidget . Widget harus diturunkan dari widget StatefulWidget untuk mendukung pemeliharaan status dan semua widget lainnya harus diturunkan dari StatefulWidget . Widget flutter adalahreactivedalam bahasa asli. Ini mirip dengan reactjs dan StatefulWidget akan dirender secara otomatis setiap kali status internalnya diubah. Rendering ulang dioptimalkan dengan menemukan perbedaan antara UI widget lama dan baru dan hanya menampilkan perubahan yang diperlukan

Lapisan

Konsep terpenting dari kerangka Flutter adalah kerangka tersebut dikelompokkan ke dalam beberapa kategori dalam hal kompleksitas dan secara jelas diatur dalam lapisan kompleksitas yang semakin berkurang. Sebuah lapisan dibangun menggunakan lapisan tingkat berikutnya segera. Lapisan paling atas adalah widget khusus untuk Android dan iOS . Lapisan berikutnya memiliki semua widget asli yang bergetar. Lapisan berikutnya adalah lapisan Rendering , yang merupakan komponen perender tingkat rendah dan merender semuanya di aplikasi flutter. Lapisan turun ke kode khusus platform inti

Gambaran umum dari sebuah layer di Flutter ditentukan dalam diagram di bawah ini -

Poin-poin berikut meringkas arsitektur Flutter -

  • Di Flutter, semuanya adalah widget dan widget kompleks terdiri dari widget yang sudah ada.

  • Fitur interaktif dapat digabungkan kapan pun diperlukan menggunakan widget GestureDetector .

  • Status widget dapat dipertahankan kapan pun diperlukan menggunakan widget StatefulWidget .

  • Flutter menawarkan desain berlapis sehingga setiap lapisan dapat diprogram tergantung pada kerumitan tugas.

Kami akan membahas semua konsep ini secara rinci di bab-bab selanjutnya.

Dart adalah bahasa pemrograman tujuan umum open source. Ini awalnya dikembangkan oleh Google. Dart adalah bahasa berorientasi objek dengan sintaks gaya C. 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.

Kode berikut menunjukkan program Dart sederhana -

void main() {
   print("Dart language is easy to learn");
}

Variabel dan tipe Data

Variabel dinamai lokasi penyimpanan dan Tipe data hanya mengacu pada jenis dan ukuran data yang terkait dengan variabel dan fungsi.

Dart menggunakan kata kunci var untuk mendeklarasikan variabel. Sintaks var didefinisikan di bawah ini,

var name = 'Dart';

Kata kunci final dan const digunakan untuk mendeklarasikan konstanta. Mereka didefinisikan seperti di bawah ini -

void main() {
   final a = 12;
   const pi = 3.14;
   print(a);
   print(pi);
}

Bahasa Dart mendukung tipe data berikut -

  • Numbers - Ini digunakan untuk mewakili literal numerik - Integer dan Double.

  • Strings- Ini mewakili urutan karakter. Nilai string ditentukan dalam tanda kutip tunggal atau ganda.

  • Booleans- Dart menggunakan kata kunci bool untuk mewakili nilai Boolean - benar dan salah.

  • Lists and Maps- Ini digunakan untuk mewakili kumpulan objek. Daftar sederhana dapat didefinisikan sebagai berikut -.

void main() {
   var list = [1,2,3,4,5];
   print(list);
}

Daftar yang ditunjukkan di atas menghasilkan daftar [1,2,3,4,5].

Peta dapat didefinisikan seperti yang ditunjukkan di sini -

void main() {
   var mapping = {'id': 1,'name':'Dart'};
   print(mapping);
}
  • Dynamic- Jika jenis variabel tidak ditentukan, maka jenis defaultnya adalah dinamis. Contoh berikut menggambarkan variabel tipe dinamis -

void main() {
   dynamic name = "Dart";
   print(name);
}

Pengambilan Keputusan dan Loop

Blok pengambilan keputusan mengevaluasi kondisi sebelum instruksi dieksekusi. Dart mendukung pernyataan If, If..else dan switch.

Loop digunakan untuk mengulang satu blok kode hingga kondisi tertentu terpenuhi. Dart mendukung loop for, for..in, while dan do.. while.

Mari kita pahami contoh sederhana tentang penggunaan pernyataan kontrol dan loop -

void main() {
   for( var i = 1 ; i <= 10; i++ ) {
      if(i%2==0) {
         print(i);
      }
   }
}

Kode di atas mencetak angka genap dari 1 hingga 10.

Fungsi

Fungsi adalah sekelompok pernyataan yang bersama-sama melakukan tugas tertentu. Mari kita lihat fungsi sederhana di Dart seperti yang ditunjukkan di sini -

void main() {
   add(3,4);
}
void add(int a,int b) {
   int c;
   c = a+b;
   print(c);
}

Fungsi di atas menambahkan dua nilai dan menghasilkan 7 sebagai keluaran.

Pemrograman berorientasi objek

Dart adalah bahasa berorientasi objek. Ini mendukung fitur pemrograman berorientasi objek seperti kelas, antarmuka, dll.

Kelas adalah cetak biru untuk membuat objek. Definisi kelas meliputi:

  • Fields
  • Getters dan setter
  • Constructors
  • Functions

Sekarang, mari kita buat kelas sederhana menggunakan definisi di atas -

class Employee {
   String name;
   
   //getter method
   String get emp_name {
      return name;
   }
   //setter method
   void set emp_name(String name) {
      this.name = name;
   }
   //function definition
   void result() {
      print(name);
   }
}
void main() {
   //object creation
   Employee emp = new Employee();
   emp.name = "employee1";
   emp.result(); //function call
}

Seperti yang kita pelajari di bab sebelumnya, widget adalah segalanya dalam kerangka Flutter. Kami telah mempelajari cara membuat widget baru di bab sebelumnya.

Dalam bab ini, mari kita pahami konsep sebenarnya di balik pembuatan widget dan berbagai jenis widget yang tersedia di kerangka Flutter .

Mari kita periksa widget MyHomePage aplikasi Hello World . Kode untuk tujuan ini adalah seperti yang diberikan di bawah ini -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar(title: Text(this.title), ), 
         body: Center(child: Text( 'Hello World',)),
      );
   }
}

Di sini, kami telah membuat widget baru dengan memperluas StatelessWidget .

Perhatikan bahwa StatelessWidget hanya membutuhkan satu metode build untuk diterapkan di kelas turunannya. The membangun metode mendapatkan lingkungan konteks yang diperlukan untuk membangun widget melalui BuildContext parameter dan mengembalikan widget itu membangun.

Dalam kode tersebut, kita telah menggunakan judul sebagai salah satu argumen konstruktor dan juga menggunakan Key sebagai argumen lain. The judul digunakan untuk menampilkan judul dan Key digunakan untuk mengidentifikasi widget di lingkungan membangun.

Di sini, membangun metode memanggil membangun metode scaffold , yang pada gilirannya memanggil membangun metode AppBar dan Pusat untuk membangun user interface-nya.

Terakhir, metode build Center memanggil metode Text build.

Untuk pemahaman yang lebih baik, representasi visual yang sama diberikan di bawah ini -

Visualisasi Bangun Widget

Di Flutter , widget dapat dikelompokkan ke dalam beberapa kategori berdasarkan fiturnya, seperti yang tercantum di bawah -

  • Widget khusus platform
  • Widget tata letak
  • Widget pemeliharaan status
  • Widget independen / dasar platform

Mari kita bahas masing-masing secara rinci sekarang.

Widget khusus platform

Flutter memiliki widget khusus untuk platform tertentu - Android atau iOS.

Widget khusus Android dirancang sesuai dengan pedoman desain Material oleh OS Android. Widget khusus Android disebut sebagai widget Material .

Widget khusus iOS dirancang sesuai dengan Panduan Antarmuka Manusia oleh Apple dan disebut sebagai widget Cupertino .

Beberapa widget material yang paling banyak digunakan adalah sebagai berikut -

  • Scaffold
  • AppBar
  • BottomNavigationBar
  • TabBar
  • TabBarView
  • ListTile
  • RaisedButton
  • FloatingActionButton
  • FlatButton
  • IconButton
  • DropdownButton
  • PopupMenuButton
  • ButtonBar
  • TextField
  • Checkbox
  • Radio
  • Switch
  • Slider
  • Pemilih Tanggal & Waktu
  • SimpleDialog
  • AlertDialog

Beberapa widget Cupertino yang paling sering digunakan adalah sebagai berikut -

  • CupertinoButton
  • CupertinoPicker
  • CupertinoDatePicker
  • CupertinoTimerPicker
  • CupertinoNavigationBar
  • CupertinoTabBar
  • CupertinoTabScaffold
  • CupertinoTabView
  • CupertinoTextField
  • CupertinoDialog
  • CupertinoDialogAction
  • CupertinoFullscreenDialogTransition
  • CupertinoPageScaffold
  • CupertinoPageTransition
  • CupertinoActionSheet
  • CupertinoActivityIndicator
  • CupertinoAlertDialog
  • CupertinoPopupSurface
  • CupertinoSlider

Widget tata letak

Di Flutter, widget dapat dibuat dengan membuat satu atau beberapa widget. Untuk membuat banyak widget menjadi satu widget, Flutter menyediakan widget dalam jumlah besar dengan fitur tata letak. Misalnya, widget anak bisa dipusatkan menggunakan widget Center .

Beberapa widget tata letak yang populer adalah sebagai berikut -

  • Container- Kotak persegi panjang yang didekorasi menggunakan widget BoxDecoration dengan latar belakang, batas, dan bayangan.

  • Center - Pusatkan widget anaknya.

  • Row - Atur anaknya dalam arah horizontal.

  • Column - Atur anaknya dalam arah vertikal.

  • Stack - Atur satu di atas yang lain.

Kami akan memeriksa widget tata letak secara detail di bab Pengantar widget tata letak yang akan datang .

Widget pemeliharaan status

Di Flutter, semua widget berasal dari StatelessWidget atau StatefulWidget .

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 dari widget dan keadaan berubah selama interaksi. Misalnya, mengetuk tombol penghitung akan menambah / mengurangi status internal penghitung satu kali dan sifat reaktif widget Flutter akan merender ulang widget secara otomatis menggunakan informasi status baru.

Kita akan mempelajari konsep widget StatefulWidget secara rinci di bab manajemen State yang akan datang .

Widget independen / dasar platform

Flutter menyediakan widget dasar dalam jumlah besar untuk membuat antarmuka pengguna yang sederhana dan kompleks dengan cara yang tidak bergantung pada platform. Mari kita lihat beberapa widget dasar di bab ini.

Text

Widget teks digunakan untuk menampilkan sepotong string. Gaya string dapat diatur dengan menggunakan properti style dan kelas TextStyle . Kode contoh untuk tujuan ini adalah sebagai berikut -

Text('Hello World!', style: TextStyle(fontWeight: FontWeight.bold))

Widget teks memiliki konstruktor khusus, Text.rich , yang menerima turunan dari tipe TextSpan untuk menentukan string dengan gaya berbeda. Widget TextSpan bersifat rekursif dan menerima TextSpan sebagai turunannya. Kode contoh untuk tujuan ini adalah sebagai berikut -

Text.rich( 
   TextSpan( 
      children: <TextSpan>[ 
         TextSpan(text: "Hello ", style:  
         TextStyle(fontStyle: FontStyle.italic)),  
         TextSpan(text: "World", style: 
         TextStyle(fontWeight: FontWeight.bold)),  
      ], 
   ), 
)

Properti terpenting dari widget Teks adalah sebagai berikut -

  • maxLines, int - Jumlah baris maksimum untuk ditampilkan

  • overflow, TextOverFlow- Tentukan bagaimana visual overflow ditangani menggunakan kelas TextOverFlow

  • style, TextStyle- Tentukan gaya string menggunakan kelas TextStyle

  • textAlign, TextAlign- Perataan teks seperti kanan, kiri, rata, dll menggunakan kelas TextAlign

  • textDirection, TextDirection - Arah teks untuk mengalir, baik dari kiri ke kanan atau kanan ke kiri

Image

Widget gambar digunakan untuk menampilkan gambar dalam aplikasi. Widget gambar menyediakan konstruktor yang berbeda untuk memuat gambar dari berbagai sumber dan itu adalah sebagai berikut -

  • Image- Pemuat gambar umum menggunakan ImageProvider

  • Image.asset - Muat gambar dari aset proyek flutter

  • Image.file - Muat gambar dari folder sistem

  • Image.memory - Muat gambar dari memori

  • Image.Network - Muat gambar dari jaringan

Opsi termudah untuk memuat dan menampilkan gambar di Flutter adalah dengan menyertakan gambar sebagai aset aplikasi dan memuatnya ke widget sesuai permintaan.

  • Buat folder, aset di folder proyek dan tempatkan gambar yang diperlukan.

  • Tentukan aset di pubspec.yaml seperti yang ditunjukkan di bawah ini -

flutter: 
   assets: 
      - assets/smiley.png
  • Sekarang, muat dan tampilkan gambar di aplikasi.

Image.asset('assets/smiley.png')
  • Source code lengkap widget MyHomePage aplikasi hello world dan hasilnya seperti gambar dibawah ini -.

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar( title: Text(this.title), ), 
         body: Center( child: Image.asset("assets/smiley.png")),
      ); 
   }
}

Gambar yang dimuat seperti yang ditunjukkan di bawah ini -

Properti terpenting dari widget Gambar adalah sebagai berikut -

  • image, ImageProvider - Gambar aktual untuk dimuat

  • width, double - Lebar gambar

  • height, double - Ketinggian gambar

  • alignment, AlignmentGeometry - Bagaimana menyelaraskan gambar dalam batas-batasnya

Icon

Widget ikon digunakan untuk menampilkan mesin terbang dari font yang dijelaskan di kelas IconData . Kode untuk memuat ikon email sederhana adalah sebagai berikut -

Icon(Icons.email)

Kode sumber lengkap untuk menerapkannya dalam aplikasi hello world adalah sebagai berikut -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),),
         body: Center( child: Icon(Icons.email)),
      );
   }
}

Ikon yang dimuat seperti yang ditunjukkan di bawah ini -

Karena konsep inti Flutter adalah Segalanya adalah widget , Flutter menggabungkan fungsionalitas tata letak antarmuka pengguna ke widget itu sendiri. Flutter menyediakan cukup banyak widget yang didesain khusus seperti Container, Center, Align , dll., Hanya untuk tujuan menata antarmuka pengguna. Widget dibuat dengan membuat widget lain biasanya menggunakan widget tata letak. Mari gunakan mempelajari konsep tata letak Flutter di bab ini.

Jenis Widget Tata Letak

Widget tata letak dapat dikelompokkan menjadi dua kategori berbeda berdasarkan anaknya -

  • Widget mendukung satu anak
  • Widget mendukung banyak anak

Mari kita pelajari kedua jenis widget dan fungsinya di bagian selanjutnya.

Widget Anak Tunggal

Dalam kategori ini, widget hanya akan memiliki satu widget sebagai turunannya dan setiap widget akan memiliki fungsi tata letak khusus.

Misalnya, widget Center hanya memusatkan widget turunannya sehubungan dengan widget induknya dan widget Container memberikan fleksibilitas lengkap untuk menempatkannya di tempat tertentu di dalamnya dengan menggunakan opsi yang berbeda seperti padding, dekorasi, dll.,

Widget anak tunggal adalah pilihan 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 -

class MyButton extends StatelessWidget {
   MyButton({Key key}) : super(key: key); 

   @override 
   Widget build(BuildContext context) {
      return Container(
         decoration: const BoxDecoration(
            border: Border(
               top: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               left: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               right: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
               bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
            ),
         ),
         child: Container(
            padding: const
            EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
            decoration: const BoxDecoration(
               border: Border(
                  top: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  left: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
                  bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
               ),
               color: Colors.grey,
            ),
            child: const Text(
               'OK',textAlign: TextAlign.center, style: TextStyle(color: Colors.black)
            ), 
         ), 
      ); 
   }
}

Di sini, kami telah menggunakan dua widget - widget Container dan widget Teks . Hasil 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 alignment . Nilai untuk properti alignment bisa disediakan oleh kelas FractionalOffset . Kelas FractionalOffset menentukan offset dalam jarak dari kiri atas.

Beberapa kemungkinan nilai offset adalah sebagai berikut -

  • FractionalOffset (1.0, 0.0) mewakili kanan atas.

  • FractionalOffset (0.0, 1.0) mewakili kiri bawah.

Kode contoh tentang offset ditunjukkan di bawah ini -

Center(
   child: Container(
      height: 100.0, 
      width: 100.0, 
      color: Colors.yellow, child: Align(
         alignment: FractionalOffset(0.2, 0.6),
         child: Container( height: 40.0, width:
            40.0, color: Colors.red,
         ), 
      ), 
   ), 
)
  • FittedBox - Ini menskalakan widget anak dan kemudian memposisikannya sesuai dengan kecocokan yang ditentukan.

  • AspectRatio - Mencoba mengukur widget anak ke rasio aspek yang ditentukan

  • ConstrainedBox

  • Baseline

  • FractinallySizedBox

  • IntrinsicHeight

  • IntrinsicWidth

  • LiimitedBox

  • OffStage

  • OverflowBox

  • SizedBox

  • SizedOverflowBox

  • Transform

  • CustomSingleChildLayout

Aplikasi hello world kami menggunakan widget tata letak berbasis material untuk mendesain halaman beranda. Mari kita memodifikasi aplikasi hello world kita untuk membangun halaman beranda menggunakan widget tata letak dasar seperti yang ditentukan di bawah -

  • Container - Generik, anak tunggal, widget wadah berbasis kotak dengan perataan, bantalan, batas, dan margin bersama dengan fitur gaya yang kaya.

  • Center - Sederhana, widget wadah anak tunggal, yang menempatkan widget anak di tengah.

Kode modifikasi dari widget MyHomePage dan MyApp adalah seperti di bawah ini -

class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
      return MyHomePage(title: "Hello World demo app");
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;
   @override
   Widget build(BuildContext context) {
      return Container(
         decoration: BoxDecoration(color: Colors.white,),
         padding: EdgeInsets.all(25), child: Center(
            child:Text(
               'Hello World', style: TextStyle(
                  color: Colors.black, letterSpacing: 0.5, fontSize: 20,
               ),
               textDirection: TextDirection.ltr,
            ),
         )
      );
   }
}

Sini,

  • Kontainer widget adalah tingkat atas atau akar widget. 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 di sini, color digunakan untuk mengatur warna container.

  • bantalan dari Kontainer widget diatur dengan menggunakan dgeInsets kelas, yang menyediakan pilihan untuk menentukan nilai padding.

  • Center adalah widget turunan dari widget Container . Sekali lagi, Text adalah anak dari Pusat widget. Teks digunakan untuk menampilkan pesan dan Pusat digunakan untuk memusatkan pesan teks sehubungan dengan widget induk, Kontainer .

Hasil akhir dari kode yang diberikan di atas adalah contoh layout seperti yang ditunjukkan di bawah ini -

Beberapa Widget Anak

Dalam kategori ini, widget tertentu akan memiliki lebih dari satu widget turunan dan tata letak setiap widget itu unik.

Misalnya, widget Baris memungkinkan penataan turunannya dalam arah horizontal, sedangkan widget Kolom memungkinkan penataan turunannya dalam arah vertikal. Dengan menyusun Row dan Column , widget dengan tingkat kerumitan apapun dapat dibangun.

Mari kita pelajari beberapa widget yang sering digunakan di bagian ini.

  • Row - Memungkinkan untuk mengatur anak-anaknya secara horizontal.

  • Column - Memungkinkan untuk mengatur anaknya secara vertikal.

  • ListView - Memungkinkan untuk mengatur anak-anaknya sebagai daftar.

  • GridView - Memungkinkan untuk mengatur anak-anaknya sebagai galeri.

  • Expanded - Digunakan untuk membuat anak-anak widget Baris dan Kolom menempati area semaksimal mungkin.

  • Table - Widget berbasis tabel.

  • Flow - Widget berbasis aliran.

  • Stack - Widget berbasis tumpukan.

Aplikasi Tata Letak Lanjutan

Di bagian ini, mari kita pelajari cara membuat antarmuka pengguna yang kompleks dari cantuman produk dengan desain khusus menggunakan widget tata letak anak tunggal dan ganda.

Untuk tujuan ini, ikuti urutan yang diberikan di bawah ini -

  • Buat aplikasi Flutter baru di studio Android, product_layout_app .

  • Ganti kode main.dart dengan kode berikut -

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

class MyApp extends StatelessWidget {
   // This widget is the root of your application.
   @override 
   Widget build(BuildContext context) {
      return MaterialApp( 
         title: 'Flutter Demo', theme: ThemeData( 
         primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page'),
      ); 
   } 
} 
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
      
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),), 
         body: Center(child: Text( 'Hello World', )), 
      ); 
   }
}
  • Here,

  • 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 ini -

  • Kode untuk ProductBox adalah sebagai berikut.

class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) 
      : super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 

   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), height: 120,  child: Card( 
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[
                  Image.asset("assets/appimages/" +image), Expanded(
                     child: Container(
                        padding: EdgeInsets.all(5), child: Column(
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[ 
                              
                              Text(this.name, style: TextStyle(fontWeight: 
                                 FontWeight.bold)), Text(this.description), 
                              Text("Price: " + this.price.toString()), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}
  • Harap perhatikan yang berikut di kode -

  • ProductBox telah menggunakan empat argumen seperti yang ditentukan di bawah ini -

    • nama - Nama produk

    • deskripsi - Deskripsi produk

    • harga - Harga produk

    • image - Gambar produk

  • ProductBox menggunakan tujuh widget bawaan seperti yang ditentukan di bawah ini -

    • Container
    • Expanded
    • Row
    • Column
    • Card
    • Text
    • Image
  • ProductBox dirancang menggunakan widget yang disebutkan di atas. Susunan atau hierarki widget ditentukan dalam diagram yang ditunjukkan di bawah ini -

  • Sekarang, letakkan 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 -

assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png

iPhone.png

Pixel.png

Laptop.png

Tablet.png

Flashdisk.png

Floppy.png

Akhirnya, Gunakan ProductBox widget di MyHomePage widget seperti yang ditentukan di bawah ini -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @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), 
            children: <Widget> [
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox(
                  name: "Pixel", 
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
  • Di sini, kami telah menggunakan ProductBox sebagai turunan dari widget ListView .

  • Kode lengkap (main.dart) dari aplikasi tata letak produk (product_layout_app) adalah sebagai berikut -

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

class MyApp extends StatelessWidget { 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', theme: ThemeData(
            primarySwatch: Colors.blue,
         ), 
         home: MyHomePage(title: 'Product layout demo home page'), 
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @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), 
            children: <Widget>[ 
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox( 
                  name: "Pixel",    
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox( 
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) :
      super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 120, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column(    
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(
                                 this.name, style: TextStyle(
                                    fontWeight: FontWeight.bold
                                 )
                              ),
                              Text(this.description), Text(
                                 "Price: " + this.price.toString()
                              ), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}

Hasil akhir dari aplikasi ini adalah sebagai berikut -

Isyarat pada dasarnya adalah cara bagi pengguna untuk berinteraksi dengan aplikasi seluler (atau perangkat berbasis sentuh apa pun). Gestur umumnya didefinisikan sebagai setiap tindakan / gerakan fisik pengguna yang bermaksud mengaktifkan kontrol tertentu dari perangkat seluler. Gestur semudah mengetuk layar perangkat seluler hingga tindakan yang lebih kompleks yang digunakan dalam aplikasi game.

Beberapa gerakan yang banyak digunakan disebutkan di sini -

  • Tap - Menyentuh permukaan perangkat dengan ujung jari sebentar lalu melepaskan ujung jari.

  • Double Tap - Mengetuk dua kali dalam waktu singkat.

  • Drag - Menyentuh permukaan perangkat dengan ujung jari lalu gerakkan ujung jari secara mantap lalu lepaskan ujung jari tersebut.

  • Flick - Mirip dengan menyeret, tetapi melakukannya dengan cara yang lebih cepat.

  • Pinch - Menjepit permukaan perangkat menggunakan dua jari.

  • Spread/Zoom - Kebalikan dari mencubit.

  • Panning - Menyentuh permukaan perangkat dengan ujung jari dan menggerakkannya ke segala arah tanpa melepaskan ujung jari.

Flutter memberikan dukungan luar biasa untuk semua jenis gerakan melalui widget eksklusifnya, GestureDetector. GestureDetector adalah widget non-visual yang utamanya digunakan untuk mendeteksi isyarat pengguna. Untuk mengidentifikasi isyarat yang ditargetkan pada widget, widget dapat ditempatkan di dalam widget GestureDetector. GestureDetector akan menangkap isyarat dan mengirimkan banyak peristiwa berdasarkan isyarat tersebut.

Beberapa gerakan dan peristiwa terkait diberikan di bawah ini -

  • Tap
    • onTapDown
    • onTapUp
    • onTap
    • onTapCancel
  • Tap dua kali
    • onDoubleTap
  • Tekan lama
    • onLongPress
  • Tarik vertikal
    • onVerticalDragStart
    • onVerticalDragUpdate
    • onVerticalDragEnd
  • Tarik horizontal
    • onHorizontalDragStart
    • onHorizontalDragUpdate
    • onHorizontalDragEnd
  • Pan
    • onPanStart
    • onPanUpdate
    • onPanEnd

Sekarang, mari kita memodifikasi aplikasi hello world dengan menyertakan fitur deteksi gerakan dan mencoba memahami konsepnya.

  • Ubah konten tubuh widget MyHomePage seperti yang ditunjukkan di bawah ini -

body: Center( 
   child: GestureDetector( 
      onTap: () { 
         _showDialog(context); 
      }, 
      child: Text( 'Hello World', ) 
   ) 
),
  • Perhatikan bahwa di sini kita telah menempatkan widget GestureDetector di atas widget Text dalam hierarki widget, menangkap event onTap dan akhirnya menampilkan jendela dialog.

  • Implementasikan fungsi * _showDialog * untuk menampilkan dialog saat pengguna membuka pesan hello world . Ia menggunakan generik showDialog dan AlertDialog widget untuk membuat widget dialog baru. Kode ditunjukkan di bawah ini -

// user defined function void _showDialog(BuildContext context) { 
   // flutter defined function 
   showDialog( 
      context: context, builder: (BuildContext context) { 
         // return object of type Dialog
         return AlertDialog( 
            title: new Text("Message"), 
            content: new Text("Hello World"),   
            actions: <Widget>[ 
               new FlatButton( 
                  child: new Text("Close"),  
                  onPressed: () {   
                     Navigator.of(context).pop();  
                  }, 
               ), 
            ], 
         ); 
      }, 
   ); 
}
  • Aplikasi akan memuat ulang perangkat menggunakan fitur Hot Reload. Sekarang, cukup klik pesan Hello World dan akan muncul dialog seperti di bawah ini -

  • Sekarang, tutup dialog dengan mengklik opsi tutup di dialog.

  • Kode lengkapnya (main.dart) adalah sebagai berikut -

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

class MyApp extends StatelessWidget { 
   // This widget is the root of your application.    
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Hello World Demo Application', 
         theme: ThemeData( primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Home page'), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   // user defined function 
   void _showDialog(BuildContext context) { 
      // flutter defined function showDialog( 
         context: context, builder: (BuildContext context) { 
            // return object of type Dialog return AlertDialog(
               title: new Text("Message"), 
               content: new Text("Hello World"),   
               actions: <Widget>[
                  new FlatButton(
                     child: new Text("Close"), 
                     onPressed: () {   
                        Navigator.of(context).pop();  
                     }, 
                  ), 
               ],
            );
         },
      );
   }
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),),
         body: Center(
            child: GestureDetector( 
               onTap: () {
                  _showDialog(context);
               },
            child: Text( 'Hello World', )
            )
         ),
      );
   }
}

Terakhir, Flutter juga menyediakan mekanisme pendeteksian isyarat tingkat rendah melalui widget Pendengar . Ini akan mendeteksi semua interaksi pengguna dan kemudian mengirimkan peristiwa berikut -

  • PointerDownEvent
  • PointerMoveEvent
  • PointerUpEvent
  • PointerCancelEvent

Flutter juga menyediakan sekumpulan kecil widget untuk melakukan gerakan khusus dan lanjutan. Widget tersebut tercantum di bawah ini -

  • Dismissible - Mendukung gerakan jentikan untuk menutup widget.

  • Draggable - Mendukung gerakan seret untuk memindahkan widget.

  • LongPressDraggable - Mendukung gerakan seret untuk memindahkan widget, ketika widget induknya juga dapat diseret.

  • DragTarget- Menerima widget yang Dapat Diseret

  • IgnorePointer - Menyembunyikan widget dan turunannya dari proses deteksi gerakan.

  • AbsorbPointer - Menghentikan proses deteksi isyarat itu sendiri sehingga widget yang tumpang tindih juga tidak dapat berpartisipasi dalam proses deteksi isyarat dan karenanya, tidak ada acara yang dimunculkan.

  • Scrollable - Mendukung pengguliran konten yang tersedia di dalam widget.

Mengelola status dalam aplikasi adalah salah satu proses terpenting dan perlu dalam siklus hidup aplikasi.

Mari kita pertimbangkan aplikasi keranjang belanja sederhana.

  • Pengguna akan masuk menggunakan kredensial mereka ke dalam aplikasi.

  • Setelah pengguna masuk, aplikasi harus mempertahankan detail pengguna yang masuk di semua layar.

  • Sekali lagi, ketika pengguna memilih produk dan menyimpannya ke dalam keranjang, informasi keranjang harus tetap ada di antara halaman-halaman sampai pengguna memeriksa keranjang.

  • Pengguna dan informasi keranjang mereka pada setiap saat disebut status aplikasi pada saat itu.

Manajemen negara dapat dibagi menjadi dua kategori berdasarkan durasi status tertentu berlangsung dalam aplikasi.

  • Ephemeral- Berlangsung selama beberapa detik seperti status animasi saat ini atau satu halaman seperti peringkat produk saat ini. Flutter mendukungnya melalui StatefulWidget.

  • app state- Terakhir untuk seluruh aplikasi seperti detail pengguna yang masuk, informasi keranjang, dll., Flutter mendukungnya melalui scoped_model.

Navigasi dan Perutean

Dalam aplikasi apa pun, menavigasi dari satu halaman / layar ke layar lainnya menentukan alur kerja aplikasi. Cara penanganan navigasi aplikasi disebut Routing. Flutter menyediakan kelas perutean dasar - MaterialPageRoute dan dua metode - Navigator.push dan Navigator.pop, untuk menentukan alur kerja aplikasi.

MaterialPageRoute

MaterialPageRoute adalah widget yang digunakan untuk merender UI-nya dengan mengganti seluruh layar dengan animasi khusus platform.

MaterialPageRoute(builder: (context) => Widget())

Di sini, pembangun akan menerima fungsi untuk membangun kontennya dengan melengkapi konteks aplikasi saat ini.

Navigation.push

Navigation.push digunakan untuk menavigasi ke layar baru menggunakan widget MaterialPageRoute.

Navigator.push( context, MaterialPageRoute(builder: (context) => Widget()), );

Navigation.pop

Navigation.pop digunakan untuk menavigasi ke layar sebelumnya.

Navigator.pop(context);

Mari kita buat aplikasi baru untuk lebih memahami konsep navigasi.

Buat aplikasi Flutter baru di studio Android, product_nav_app

  • Salin folder aset dari product_nav_app ke product_state_app dan tambahkan aset di dalam file pubspec.yaml.

flutter:
   assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png
  • Ganti kode startup default (main.dart) dengan kode startup kita.

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

class MyApp extends StatelessWidget { 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) { 
      return MaterialApp( 
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Product state demo home page'
         ),
      );
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title), 
         ), 
         body: Center(
            child: Text('Hello World',)
         ), 
      ); 
   } 
}
  • Mari kita buat kelas Produk untuk mengatur informasi produk.

class Product { 
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Product(this.name, this.description, this.price, this.image); 
}
  • Mari kita tulis metode getProducts di kelas Produk untuk menghasilkan catatan produk tiruan kita.

static List<Product> getProducts() {
   List<Product> items = <Product>[]; 
   
   items.add(
      Product( 
         "Pixel", 
         "Pixel is the most feature-full phone ever", 800, 
         "pixel.png"
      )
   ); 
   items.add(
      Product(
         "Laptop", 
         "Laptop is most productive development tool", 
         2000, "
         laptop.png"
      )
   ); 
   items.add(
      Product( 
         "Tablet", 
         "Tablet is the most useful device ever for meeting", 
         1500, 
         "tablet.png"
      )
   ); 
   items.add(
      Product( 
         "Pendrive", 
         "Pendrive is useful storage medium",
         100, 
         "pendrive.png"
      )
   ); 
   items.add(
      Product( 
         "Floppy Drive", 
         "Floppy drive is useful rescue storage medium", 
         20, 
         "floppy.png"
      )
   ); 
   return items; 
}
import product.dart in main.dart
import 'Product.dart';
  • Mari kita sertakan widget baru kita, RatingBox.

class RatingBox extends StatefulWidget {
   @override 
   _RatingBoxState createState() =>_RatingBoxState(); 
} 
class _RatingBoxState extends State<RatingBox> {
   int _rating = 0; 
   void _setRatingAsOne() {
      setState(() {
         _rating = 1; 
      }); 
   } 
   void _setRatingAsTwo() {
      setState(() {
         _rating = 2; 
      }); 
   }
   void _setRatingAsThree() {
      setState(() {
         _rating = 3;
      });
   }
   Widget build(BuildContext context) {
      double _size = 20; 
      print(_rating); 
      return Row(
         mainAxisAlignment: MainAxisAlignment.end, 
         crossAxisAlignment: CrossAxisAlignment.end, 
         mainAxisSize: MainAxisSize.max, 
         children: <Widget>[
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 1? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon(
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsOne, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 2? 
                     Icon(
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon(
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsTwo, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 3 ? 
                     Icon(
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsThree, 
                  iconSize: _size, 
               ), 
            ), 
         ], 
      ); 
   }
}
  • Mari kita memodifikasi widget ProductBox kita untuk bekerja dengan kelas Produk baru kita.

class ProductBox extends StatelessWidget {    
   ProductBox({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card( 
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + this.item.image), 
                  Expanded(
                     child: Container(
                        padding: EdgeInsets.all(5), 
                        child: Column(
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[
                              Text(this.item.name, 
                              style: TextStyle(fontWeight: FontWeight.bold)), 
                              Text(this.item.description), 
                              Text("Price: " + this.item.price.toString()), 
                              RatingBox(), 
                           ], 
                        )
                     )
                  )
               ]
            ), 
         )
      ); 
   }
}

Mari kita tulis ulang widget MyHomePage kita untuk bekerja dengan model Produk dan untuk membuat daftar semua produk menggunakan ListView.

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   final items = Product.getProducts(); 
   
   @override 
   Widget build(BuildContext context) { 
      return Scaffold( appBar: AppBar(title: Text("Product Navigation")), 
      body: ListView.builder( 
         itemCount: items.length, 
         itemBuilder: (context, index) {
            return GestureDetector( 
               child: ProductBox(item: items[index]), 
               onTap: () { 
                  Navigator.push( 
                     context, MaterialPageRoute( 
                        builder: (context) => ProductPage(item: items[index]), 
                     ), 
                  ); 
               }, 
            ); 
         }, 
      )); 
   } 
}

Di sini, kami telah menggunakan MaterialPageRoute untuk menavigasi ke halaman detail produk.

  • Sekarang, mari kita tambahkan ProductPage untuk menampilkan detail produk.

class ProductPage extends StatelessWidget { 
   ProductPage({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar( 
            title: Text(this.item.name), 
         ), 
         body: Center(
            child: Container(
               padding: EdgeInsets.all(0), 
               child: Column(
                  mainAxisAlignment: MainAxisAlignment.start, 
                  crossAxisAlignment: CrossAxisAlignment.start, 
                  children: <Widget>[
                     Image.asset("assets/appimages/" + this.item.image), 
                     Expanded(
                        child: Container(
                           padding: EdgeInsets.all(5), 
                           child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[
                                 Text(
                                    this.item.name, style: TextStyle(
                                       fontWeight: FontWeight.bold
                                    )
                                 ), 
                                 Text(this.item.description), 
                                 Text("Price: " + this.item.price.toString()), 
                                 RatingBox(),
                              ], 
                           )
                        )
                     )
                  ]
               ), 
            ), 
         ), 
      ); 
   } 
}

Kode lengkap aplikasi adalah sebagai berikut -

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

class Product {
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Product(this.name, this.description, this.price, this.image); 
   
   static List<Product> getProducts() {
      List<Product> items = <Product>[]; 
      items.add(
         Product(
            "Pixel", 
            "Pixel is the most featureful phone ever", 
            800, 
            "pixel.png"
         )
      );
      items.add(
         Product(
            "Laptop", 
            "Laptop is most productive development tool", 
            2000, 
            "laptop.png"
         )
      ); 
      items.add(
         Product(
            "Tablet", 
            "Tablet is the most useful device ever for meeting", 
            1500, 
            "tablet.png"
         )
      ); 
      items.add(
         Product( 
            "Pendrive", 
            "iPhone is the stylist phone ever", 
            100, 
            "pendrive.png"
         )
      ); 
      items.add(
         Product(
            "Floppy Drive", 
            "iPhone is the stylist phone ever", 
            20, 
            "floppy.png"
         )
      ); 
      items.add(
         Product(
            "iPhone", 
            "iPhone is the stylist phone ever", 
            1000, 
            "iphone.png"
         )
      ); 
      return items; 
   }
}
class MyApp extends StatelessWidget {
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(title: 'Product Navigation demo home page'), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   final items = Product.getProducts(); 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text("Product Navigation")), 
         body: ListView.builder( 
            itemCount: items.length, 
            itemBuilder: (context, index) { 
               return GestureDetector( 
                  child: ProductBox(item: items[index]), 
                  onTap: () { 
                     Navigator.push( 
                        context, 
                        MaterialPageRoute( 
                           builder: (context) => ProductPage(item: items[index]), 
                        ), 
                     ); 
                  }, 
               ); 
            }, 
         )
      ); 
   }
} 
class ProductPage extends StatelessWidget {
   ProductPage({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.item.name), 
         ), 
         body: Center(
            child: Container( 
               padding: EdgeInsets.all(0), 
               child: Column( 
                  mainAxisAlignment: MainAxisAlignment.start, 
                  crossAxisAlignment: CrossAxisAlignment.start, 
                  children: <Widget>[ 
                     Image.asset("assets/appimages/" + this.item.image), 
                     Expanded( 
                        child: Container( 
                           padding: EdgeInsets.all(5), 
                           child: Column( 
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[ 
                                 Text(this.item.name, style: TextStyle(fontWeight: FontWeight.bold)), 
                                 Text(this.item.description), 
                                 Text("Price: " + this.item.price.toString()), 
                                 RatingBox(), 
                              ], 
                           )
                        )
                     ) 
                  ]
               ), 
            ), 
         ), 
      ); 
   } 
}
class RatingBox extends StatefulWidget { 
   @override 
   _RatingBoxState createState() => _RatingBoxState(); 
} 
class _RatingBoxState extends State<RatingBox> { 
   int _rating = 0;
   void _setRatingAsOne() {
      setState(() {
         _rating = 1; 
      }); 
   }
   void _setRatingAsTwo() {
      setState(() {
         _rating = 2; 
      }); 
   } 
   void _setRatingAsThree() { 
      setState(() {
         _rating = 3; 
      }); 
   }
   Widget build(BuildContext context) {
      double _size = 20; 
      print(_rating); 
      return Row(
         mainAxisAlignment: MainAxisAlignment.end, 
         crossAxisAlignment: CrossAxisAlignment.end, 
         mainAxisSize: MainAxisSize.max, 
         children: <Widget>[
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 1 ? Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsOne, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton( 
                  icon: (
                     _rating >= 2 ? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsTwo, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 3 ? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     )
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsThree, 
                  iconSize: _size, 
               ), 
            ), 
         ], 
      ); 
   } 
} 
class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + this.item.image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(this.item.name, style: TextStyle(fontWeight: FontWeight.bold)), Text(this.item.description), 
                              Text("Price: " + this.item.price.toString()), 
                              RatingBox(), 
                           ], 
                        )
                     )
                  ) 
               ]
            ), 
         )
      ); 
   } 
}

Jalankan aplikasi dan klik salah satu item produk. Ini akan menunjukkan halaman detail yang relevan. Kita dapat pindah ke halaman muka dengan mengklik tombol kembali. Halaman daftar produk dan halaman detail produk dari aplikasi ditampilkan sebagai berikut -

Animasi adalah prosedur yang rumit 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.

pengantar

Animasi adalah proses menampilkan rangkaian gambar / gambar dengan urutan tertentu dalam durasi tertentu untuk memberikan ilusi gerakan. Aspek terpenting dari animasi adalah sebagai berikut -

  • Animasi memiliki dua nilai berbeda: Nilai awal dan Nilai akhir. Animasi dimulai dari nilai Awal dan melewati serangkaian nilai antara dan akhirnya berakhir di nilai Akhir. Misalnya, untuk menganimasikan widget agar menghilang, nilai awalnya adalah opasitas penuh dan nilai akhirnya adalah opasitas nol.

  • Nilai antara mungkin bersifat linier atau non-linier (kurva) dan dapat dikonfigurasi. Pahami bahwa animasi berfungsi seperti yang dikonfigurasi. Setiap konfigurasi memberikan nuansa animasi yang berbeda. Misalnya, memudarkan widget akan bersifat linier sedangkan memantul bola akan bersifat non-linier.

  • Durasi proses animasi memengaruhi kecepatan (kelambatan atau kecepatan luntur) animasi.

  • Kemampuan untuk mengontrol proses animasi seperti memulai animasi, menghentikan animasi, mengulang animasi untuk mengatur berapa kali, membalik proses animasi, dll.,

  • Di Flutter, sistem animasi tidak melakukan animasi nyata. Sebagai gantinya, ini hanya memberikan nilai yang diperlukan di setiap bingkai untuk merender gambar.

Kelas Berbasis Animasi

Sistem animasi Flutter didasarkan pada objek Animation. Kelas animasi inti dan penggunaannya adalah sebagai berikut -

Animasi

Menghasilkan nilai interpolasi antara dua angka selama durasi tertentu. Kelas Animasi yang paling umum adalah -

  • Animation<double> - menginterpolasi nilai antara dua angka desimal

  • Animation<Color> - interpolasi warna antara dua warna

  • Animation<Size> - ukuran interpolasi antara dua ukuran

  • 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

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this);

Di sini, pengontrol mengontrol opsi animasi dan 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-linier. CurvedAnimation dapat digunakan bersama dengan objek Animation seperti di bawah ini -

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this); 
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn)

Tween <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.

AnimationController controller = AnimationController( 
   duration: const Duration(milliseconds: 1000), 
vsync: this); Animation<int> customTween = IntTween(
   begin: 0, end: 255).animate(controller);
  • Tween juga dapat digunakan bersama CurvedAnimation seperti di bawah ini -

AnimationController controller = AnimationController(
   duration: const Duration(milliseconds: 500), vsync: this); 
final Animation curve = CurvedAnimation(parent: controller, curve: Curves.easeOut); 
Animation<int> customTween = IntTween(begin: 0, end: 255).animate(curve);

Di sini, pengontrol adalah pengontrol animasi yang sebenarnya. curve memberikan jenis non-linearitas dan customTween menyediakan rentang khusus dari 0 hingga 255.

Alur kerja Animasi Flutter

Alur kerja animasinya adalah sebagai berikut -

  • Tentukan dan mulai pengontrol animasi di initState dari StatefulWidget.

AnimationController(duration: const Duration(seconds: 2), vsync: this); 
animation = Tween<double>(begin: 0, end: 300).animate(controller); 
controller.forward();
  • Tambahkan pendengar berbasis animasi, addListener untuk mengubah status widget.

animation = Tween<double>(begin: 0, end: 300).animate(controller) ..addListener(() {
   setState(() { 
      // The state that has changed here is the animation object’s value. 
   }); 
});
  • Widget built-in, 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 build widget, lalu terapkan untuk lebar, tinggi, atau properti apa pun yang relevan, bukan nilai aslinya.

child: Container( 
   height: animation.value, 
   width: animation.value, 
   child: <Widget>, 
)

Aplikasi Kerja

Mari kita tulis aplikasi berbasis animasi sederhana untuk memahami konsep animasi dalam framework Flutter.

  • Buat aplikasi Flutter baru di studio Android, product_animation_app.

  • Salin folder aset dari product_nav_app ke product_animation_app dan tambahkan aset di dalam file pubspec.yaml.

flutter: 
   assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png
  • Hapus kode startup default (main.dart).

  • Tambahkan impor dan fungsi utama dasar.

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());
  • Buat widget MyApp berasal dari StatefulWidgtet.

class MyApp extends StatefulWidget { 
   _MyAppState createState() => _MyAppState(); 
}
  • Buat widget _MyAppState dan implementasikan initState serta buang selain metode build default.

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { 
   Animation<double> animation; 
   AnimationController controller; 
   @override void initState() {
      super.initState(); 
      controller = AnimationController(
         duration: const Duration(seconds: 10), vsync: this
      ); 
      animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
      controller.forward(); 
   } 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      controller.forward(); 
      return MaterialApp(
         title: 'Flutter Demo',
         theme: ThemeData(primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page', animation: animation,)
      ); 
   } 
   @override 
   void dispose() {
      controller.dispose();
      super.dispose();
   }
}

Sini,

  • Dalam metode initState, kita telah membuat objek pengontrol animasi (pengontrol), objek animasi (animasi) dan memulai animasi menggunakan controller.forward.

  • Dalam metode pembuangan, kita telah membuang objek pengontrol animasi (pengontrol).

  • Dalam metode build, kirim animasi ke widget MyHomePage melalui konstruktor. Sekarang, widget MyHomePage dapat menggunakan objek animasi untuk menganimasikan kontennya.

  • Sekarang, tambahkan widget ProductBox

class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image})
      : super(key: key);
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card( 
            child: Row( 
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(this.name, style: 
                                 TextStyle(fontWeight: FontWeight.bold)), 
                              Text(this.description), 
                                 Text("Price: " + this.price.toString()), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      ); 
   }
}
  • Buat widget baru, MyAnimatedWidget untuk melakukan animasi fade sederhana menggunakan opacity.

class MyAnimatedWidget extends StatelessWidget { 
   MyAnimatedWidget({this.child, this.animation}); 
      
   final Widget child; 
   final Animation<double> animation; 
   
   Widget build(BuildContext context) => Center( 
   child: AnimatedBuilder(
      animation: animation, 
      builder: (context, child) => Container( 
         child: Opacity(opacity: animation.value, child: child), 
      ), 
      child: child), 
   ); 
}
  • Di sini, kami telah menggunakan AniatedBuilder untuk melakukan animasi kami. AnimatedBuilder adalah widget yang membangun kontennya sambil melakukan animasi pada saat yang bersamaan. Ini menerima objek animasi untuk mendapatkan nilai animasi saat ini. Kami telah menggunakan nilai animasi, animation.value untuk mengatur opasitas widget anak. Akibatnya, widget akan menganimasikan widget anak menggunakan konsep opasitas.

  • Terakhir, buat widget MyHomePage dan gunakan objek animasi untuk menganimasikan kontennya.

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title, this.animation}) : super(key: key); 
   
   final String title; 
   final Animation<double> 
   animation; 
   
   @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), 
            children: <Widget>[
               FadeTransition(
                  child: ProductBox(
                     name: "iPhone", 
                     description: "iPhone is the stylist phone ever", 
                     price: 1000, 
                     image: "iphone.png"
                  ), opacity: animation
               ), 
               MyAnimatedWidget(child: ProductBox(
                  name: "Pixel", 
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), animation: animation), 
               ProductBox(
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox(
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ),
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ),
            ],
         )
      );
   }
}

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 opasitas.

  • Kode lengkapnya adalah sebagai berikut -

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

class MyApp extends StatefulWidget { 
   _MyAppState createState() => _MyAppState(); 
} 
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
   Animation<double> animation; 
   AnimationController controller; 
   
   @override 
   void initState() {
      super.initState(); 
      controller = AnimationController(
         duration: const Duration(seconds: 10), vsync: this); 
      animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
      controller.forward(); 
   } 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      controller.forward(); 
      return MaterialApp( 
         title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page', animation: animation,) 
      ); 
   } 
   @override 
   void dispose() {
      controller.dispose();
      super.dispose(); 
   } 
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title, this.animation}): super(key: key);
   final String title; 
   final Animation<double> animation; 
   
   @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), 
            children: <Widget>[
               FadeTransition(
                  child: ProductBox(
                     name: "iPhone", 
                     description: "iPhone is the stylist phone ever", 
                     price: 1000, 
                     image: "iphone.png"
                  ), 
                  opacity: animation
               ), 
               MyAnimatedWidget(
                  child: ProductBox( 
                     name: "Pixel", 
                     description: "Pixel is the most featureful phone ever", 
                     price: 800, 
                     image: "pixel.png"
                  ), 
                  animation: animation
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox(
                  name: "Tablet",
                  description: "Tablet is the most useful device ever for meeting",
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ], 
         )
      ); 
   } 
} 
class ProductBox extends StatelessWidget { 
   ProductBox({Key key, this.name, this.description, this.price, this.image}) :
      super(key: key);
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded(
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(
                                 this.name, style: TextStyle(
                                    fontWeight: FontWeight.bold
                                 )
                              ), 
                              Text(this.description), Text(
                                 "Price: " + this.price.toString()
                              ), 
                           ], 
                        )
                     )
                  ) 
               ]
            )
         )
      ); 
   } 
}
class MyAnimatedWidget extends StatelessWidget { 
   MyAnimatedWidget({this.child, this.animation}); 
   final Widget child; 
   final Animation<double> animation; 
 
   Widget build(BuildContext context) => Center( 
      child: AnimatedBuilder(
         animation: animation, 
         builder: (context, child) => Container( 
            child: Opacity(opacity: animation.value, child: child), 
         ), 
         child: child
      ), 
   ); 
}
  • Kompilasi dan jalankan aplikasi untuk melihat hasilnya. Versi awal dan akhir aplikasi adalah sebagai berikut -

Flutter menyediakan kerangka umum untuk mengakses fitur khusus platform. Ini memungkinkan pengembang untuk memperluas fungsionalitas kerangka Flutter menggunakan kode khusus platform. Fungsionalitas spesifik platform seperti kamera, level baterai, browser, dll., Dapat diakses dengan mudah melalui framework.

Ide umum untuk mengakses kode khusus platform adalah melalui protokol perpesanan sederhana. Kode Flutter, Klien dan kode platform serta Host mengikat ke Saluran Pesan umum. Klien mengirim pesan ke Host melalui Message Channel. Host mendengarkan di Message Channel, menerima pesan dan melakukan fungsionalitas yang diperlukan dan akhirnya, mengembalikan hasilnya ke Klien melalui Message Channel.

Arsitektur kode khusus platform ditunjukkan pada 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 dererialisasi berfungsi secara transparan antara klien dan host.

Mari kita tulis aplikasi sederhana untuk membuka browser menggunakan Android SDK dan memahami caranya

  • Buat aplikasi Flutter baru di studio Android, flutter_browser_app

  • Ganti kode main.dart dengan kode di bawah ini -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(title: 'Flutter Demo Home Page'),
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @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 mengatur metode onPressed sebagai null.

  • Sekarang, impor paket berikut -

import 'dart:async'; 
import 'package:flutter/services.dart';
  • Di sini, services.dart menyertakan fungsionalitas untuk memanggil kode khusus platform.

  • Buat saluran pesan baru di widget MyHomePage.

static const platform = const 
MethodChannel('flutterapp.tutorialspoint.com/browser');
  • Tulis metode, _openBrowser untuk memanggil metode khusus platform, metode openBrowser melalui saluran pesan.

Future<void> _openBrowser() async { 
   try {
      final int result = await platform.invokeMethod(
         'openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         }
      ); 
   } 
   on PlatformException catch (e) { 
      // Unable to open the browser 
      print(e); 
   }
}

Di sini, kami telah menggunakan platform.invokeMethod untuk menjalankan openBrowser (dijelaskan dalam 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 perpustakaan yang diperlukan -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel; 
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant;
  • Tulis metode, openBrowser untuk membuka browser

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = this; 
   if (activity == null) { 
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground 
      activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • Sekarang, setel nama saluran di kelas MainActivity -

private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
  • Tulis kode khusus android untuk menyetel penanganan pesan dalam metode onCreate -

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( 
   new MethodCallHandler() { 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      String url = call.argument("url"); 
      if (call.method.equals("openBrowser")) {
         openBrowser(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
});

Di sini, kami telah membuat saluran pesan menggunakan kelas MethodChannel dan menggunakan kelas MethodCallHandler untuk menangani pesan tersebut. onMethodCall adalah metode sebenarnya yang bertanggung jawab untuk memanggil kode khusus platform yang benar dengan memeriksa pesannya. Metode onMethodCall mengekstrak url dari pesan dan kemudian memanggil openBrowser hanya jika pemanggilan metode adalah openBrowser. Jika tidak, ia mengembalikan metode notImplemented.

Kode sumber lengkap dari aplikasi ini adalah sebagai berikut -

main.dart

MainActivity.java

package com.tutorialspoint.flutterapp.flutter_browser_app; 

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant; 

public class MainActivity extends FlutterActivity { 
   private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser"; 
   @Override 
   protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      GeneratedPluginRegistrant.registerWith(this); 
      new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
         new MethodCallHandler() {
            @Override 
            public void onMethodCall(MethodCall call, Result result) {
               String url = call.argument("url"); 
               if (call.method.equals("openBrowser")) { 
                  openBrowser(call, result, url); 
               } else { 
                  result.notImplemented(); 
               }
            }
         }
      ); 
   }
   private void openBrowser(MethodCall call, Result result, String url) {
      Activity activity = this; if (activity == null) {
         result.error(
            "ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null
         ); 
         return; 
      } 
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   }
}

main.dart

import 'package:flutter/material.dart'; 
import 'dart:async'; 
import 'package:flutter/services.dart'; 

void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget {
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   static const platform = const MethodChannel('flutterapp.tutorialspoint.com/browser'); 
   Future<void> _openBrowser() async {
      try {
         final int result = await platform.invokeMethod('openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         });
      }
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      } 
   }
   @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 - Halaman beranda seperti yang ditunjukkan pada tangkapan layar di sini -

Mengakses kode khusus iOS mirip dengan yang ada di platform Android kecuali menggunakan bahasa khusus iOS - Objective-C atau Swift dan iOS SDK. Jika tidak, konsepnya sama dengan platform Android.

Mari kita tulis aplikasi yang sama seperti pada bab sebelumnya untuk platform iOS juga.

  • Mari kita buat aplikasi baru di Android Studio (macOS), flutter_browser_ios_app

  • Ikuti langkah 2 - 6 seperti pada bab sebelumnya.

  • Mulai Xcode dan klik File → Open

  • Pilih proyek xcode di bawah direktori ios dari proyek flutter kami.

  • Buka AppDelegate.m di bawah Runner → Runner path. Ini berisi kode berikut -

#include "AppDelegate.h" 
#include "GeneratedPluginRegistrant.h" 
@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      // [GeneratedPluginRegistrant registerWithRegistry:self];
      // Override point for customization after application launch.
      return [super application:application didFinishLaunchingWithOptions:launchOptions];
   } 
@end
  • Kami telah menambahkan metode, openBrowser untuk membuka browser dengan url tertentu. Ini menerima argumen tunggal, url.

- (void)openBrowser:(NSString *)urlString { 
   NSURL *url = [NSURL URLWithString:urlString]; 
   UIApplication *application = [UIApplication sharedApplication]; 
   [application openURL:url]; 
}
  • Dalam metode didFinishLaunchingWithOptions, temukan pengontrol dan setel ke variabel pengontrol.

FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
  • Dalam metode didFinishLaunchingWithOptions, setel saluran browser sebagai flutterapp.tutorialspoint.com/browse -

FlutterMethodChannel* browserChannel = [
   FlutterMethodChannel methodChannelWithName:
   @"flutterapp.tutorialspoint.com/browser" binaryMessenger:controller];
  • Buat variabel, weakSelf dan setel kelas saat ini -

__weak typeof(self) weakSelf = self;
  • Sekarang, implementasikan setMethodCallHandler. Panggil openBrowser dengan mencocokkan call.method. Dapatkan url dengan memanggil call.arguments dan meneruskannya saat memanggil openBrowser.

[browserChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
   if ([@"openBrowser" isEqualToString:call.method]) { 
      NSString *url = call.arguments[@"url"];   
      [weakSelf openBrowser:url]; 
   } else { result(FlutterMethodNotImplemented); } 
}];
  • Kode lengkapnya adalah sebagai berikut -

#include "AppDelegate.h" 
#include "GeneratedPluginRegistrant.h" 
@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application 
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
   // custom code starts 
   FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; 
   FlutterMethodChannel* browserChannel = [
      FlutterMethodChannel methodChannelWithName:
      @"flutterapp.tutorialspoint.com /browser" binaryMessenger:controller]; 
   
   __weak typeof(self) weakSelf = self; 
   [browserChannel setMethodCallHandler:^(
      FlutterMethodCall* call, FlutterResult result) { 
      
      if ([@"openBrowser" isEqualToString:call.method]) { 
         NSString *url = call.arguments[@"url"];
         [weakSelf openBrowser:url]; 
      } else { result(FlutterMethodNotImplemented); } 
   }]; 
   // custom code ends 
   [GeneratedPluginRegistrant registerWithRegistry:self]; 
   
   // Override point for customization after application launch. 
   return [super application:application didFinishLaunchingWithOptions:launchOptions]; 
}
- (void)openBrowser:(NSString *)urlString { 
   NSURL *url = [NSURL URLWithString:urlString]; 
   UIApplication *application = [UIApplication sharedApplication]; 
   [application openURL:url]; 
} 
@end
  • Buka pengaturan proyek.

  • Pergi ke Capabilities dan aktifkan Background Modes.

  • Menambahkan *Background fetch dan Remote Notification**.

  • Sekarang, jalankan aplikasinya. Ini berfungsi mirip dengan versi Android tetapi browser Safari akan dibuka, bukan chrome.

Cara Dart mengatur dan berbagi sekumpulan fungsionalitas adalah melalui Package. Dart Package hanyalah pustaka atau modul yang dapat dibagikan. Secara umum Dart Package sama dengan Dart Application kecuali Dart Package tidak memiliki entry point aplikasi, main.

Struktur umum Package (pertimbangkan paket demo, my_demo_package) adalah sebagai berikut -

  • lib/src/* - File kode Dart pribadi.

  • lib/my_demo_package.dart- File kode Dart Utama. Itu dapat diimpor ke aplikasi sebagai -

import 'package:my_demo_package/my_demo_package.dart'
  • File kode pribadi lainnya dapat diekspor ke file kode utama (my_demo_package.dart), jika perlu seperti yang ditunjukkan di bawah ini -

export src/my_private_code.dart
  • lib/*- Sejumlah file kode Dart yang diatur dalam struktur folder kustom apa pun. Kode dapat diakses sebagai,

import 'package:my_demo_package/custom_folder/custom_file.dart'
  • pubspec.yaml - Spesifikasi proyek, sama dengan aplikasi,

Semua file kode Dart dalam Package hanyalah kelas Dart dan tidak memiliki persyaratan khusus untuk kode Dart untuk memasukkannya ke dalam Package.

Jenis Paket

Karena Paket Dart pada dasarnya adalah kumpulan kecil dari fungsionalitas serupa, itu dapat dikategorikan berdasarkan fungsinya.

Paket Dart

Kode Dart umum, 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 (tentukan jumlah suku kata dalam satu kata.

Paket Flutter

Kode Dart generik, yang bergantung pada framework Flutter dan hanya dapat digunakan di lingkungan seluler. Misalnya, fluro adalah router khusus untuk flutter. Itu tergantung pada kerangka Flutter.

Plugin Flutter

Kode Dart generik, yang bergantung pada framework Flutter serta kode platform yang mendasarinya (Android SDK atau iOS SDK). Misalnya kamera adalah sebuah plugin untuk berinteraksi dengan kamera perangkat. Itu tergantung pada kerangka Flutter serta kerangka dasar untuk mendapatkan akses ke kamera.

Menggunakan Paket Dart

Paket Dart dihosting dan dipublikasikan ke server langsung, https://pub.dartlang.org.Selain itu, Flutter menyediakan alat sederhana, pub untuk mengelola Paket Dart dalam aplikasi. Langkah-langkah yang diperlukan untuk menggunakan Package adalah sebagai berikut -

  • Sertakan nama paket dan versi yang diperlukan ke dalam pubspec.yaml seperti yang ditunjukkan di bawah ini -

dependencies: english_words: ^3.1.5
  • Nomor versi terbaru dapat ditemukan dengan memeriksa server online.

  • Instal paket ke dalam aplikasi dengan menggunakan perintah berikut -

flutter packages get
  • Saat mengembangkan di studio Android, Android Studio mendeteksi perubahan apa pun 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';
  • Gunakan metode apa pun yang tersedia dalam paket,

nouns.take(50).forEach(print);
  • Di sini, kami telah menggunakan fungsi kata benda untuk mendapatkan dan mencetak 50 kata teratas.

Kembangkan Paket Plugin Flutter

Mengembangkan Flutter Plugin mirip dengan mengembangkan aplikasi Dart atau Dart Package. Satu-satunya pengecualian adalah plugin akan menggunakan API Sistem (Android atau iOS) untuk mendapatkan fungsionalitas khusus platform yang diperlukan.

Karena kita telah mempelajari cara mengakses kode platform pada bab sebelumnya, mari kita kembangkan plugin sederhana, my_browser untuk memahami proses pengembangan plugin. Fungsionalitas plugin my_browser adalah untuk memungkinkan aplikasi membuka situs web yang diberikan di browser khusus platform.

  • Mulai Android Studio.

  • Klik File → New Flutter Project dan pilih opsi Flutter Plugin.

  • Anda dapat melihat jendela pemilihan plugin Flutter seperti yang ditunjukkan di sini -

  • Masukkan my_browser sebagai nama proyek dan klik Next.

  • Masukkan nama plugin dan detail lainnya di jendela seperti yang ditunjukkan di sini -

  • Masukkan domain perusahaan, flutterplugins.tutorialspoint.com di jendela yang ditunjukkan di bawah ini dan kemudian klik Finish. Ini akan menghasilkan kode startup untuk mengembangkan plugin baru kami.

  • Buka file my_browser.dart dan tulis metode, openBrowser untuk menjalankan metode openBrowser khusus platform.

Future<void> openBrowser(String urlString) async { 
   try {
      final int result = await _channel.invokeMethod(
         'openBrowser', <String, String>{ 'url': urlString }
      );
   }
   on PlatformException catch (e) { 
      // Unable to open the browser print(e); 
   } 
}
  • Buka file MyBrowserPlugin.java dan impor kelas berikut -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle;
  • Di sini, kita harus mengimpor pustaka yang diperlukan untuk membuka browser dari Android.

  • Tambahkan mRegistrar variabel pribadi baru dari jenis Registrar di kelas MyBrowserPlugin.

private final Registrar mRegistrar;
  • Di sini, Registrar digunakan untuk mendapatkan informasi konteks dari kode pemanggilan.

  • Tambahkan konstruktor untuk menyetel Registrar di kelas MyBrowserPlugin.

private MyBrowserPlugin(Registrar registrar) { 
   this.mRegistrar = registrar; 
}
  • Ubah registerWith untuk menyertakan konstruktor baru kita di kelas MyBrowserPlugin.

public static void registerWith(Registrar registrar) { 
   final MethodChannel channel = new MethodChannel(registrar.messenger(), "my_browser"); 
   MyBrowserPlugin instance = new MyBrowserPlugin(registrar); 
   channel.setMethodCallHandler(instance); 
}
  • Ubah onMethodCall untuk menyertakan metode openBrowser di kelas MyBrowserPlugin.

@Override 
public void onMethodCall(MethodCall call, Result result) { 
   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(call, result, url); 
   } else { 
      result.notImplemented(); 
   } 
}
  • Tulis metode openBrowser khusus platform untuk mengakses browser di kelas MyBrowserPlugin.

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = mRegistrar.activity(); 
   if (activity == null) {
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • Kode sumber lengkap plugin my_browser adalah sebagai berikut -

my_browser.dart

import 'dart:async'; 
import 'package:flutter/services.dart'; 

class MyBrowser {
   static const MethodChannel _channel = const MethodChannel('my_browser'); 
   static Future<String> get platformVersion async { 
      final String version = await _channel.invokeMethod('getPlatformVersion'); return version; 
   } 
   Future<void> openBrowser(String urlString) async { 
      try {
         final int result = await _channel.invokeMethod(
            'openBrowser', <String, String>{'url': urlString}); 
      } 
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      }
   }
}

MyBrowserPlugin.java

package com.tutorialspoint.flutterplugins.my_browser; 

import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel; 
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugin.common.PluginRegistry.Registrar; 
import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

/** MyBrowserPlugin */ 
public class MyBrowserPlugin implements MethodCallHandler {
   private final Registrar mRegistrar; 
   private MyBrowserPlugin(Registrar registrar) { 
      this.mRegistrar = registrar; 
   } 
   /** Plugin registration. */
   public static void registerWith(Registrar registrar) {
      final MethodChannel channel = new MethodChannel(
         registrar.messenger(), "my_browser"); 
      MyBrowserPlugin instance = new MyBrowserPlugin(registrar); 
      channel.setMethodCallHandler(instance); 
   } 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      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(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
   private void openBrowser(MethodCall call, Result result, String url) { 
      Activity activity = mRegistrar.activity(); 
      if (activity == null) {
         result.error("ACTIVITY_NOT_AVAILABLE",
            "Browser cannot be opened without foreground activity", null); 
         return; 
      }
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   } 
}
  • Buat proyek baru, my_browser_plugin_test untuk menguji plugin kami yang baru dibuat.

  • Buka pubspec.yaml dan setel my_browser sebagai dependensi plugin.

dependencies: 
   flutter: 
      sdk: flutter 
   my_browser: 
      path: ../my_browser
  • Android studio akan memperingatkan bahwa pubspec.yaml diperbarui seperti yang ditunjukkan dalam peringatan paket studio Android yang diberikan di bawah ini -

  • Klik Dapatkan opsi ketergantungan. Android studio akan mendapatkan paket dari Internet dan mengkonfigurasinya dengan benar untuk aplikasi.

  • Buka main.dart dan sertakan plugin my_browser seperti di bawah ini -

import 'package:my_browser/my_browser.dart';
  • Panggil fungsi openBrowser dari plugin my_browser seperti yang ditunjukkan di bawah ini -

onPressed: () => MyBrowser().openBrowser("https://flutter.dev"),
  • Kode lengkap main.dart adalah sebagai berikut -

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

void main() => runApp(MyApp()); 

class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp( 
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      );,
   }
} 
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar( 
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton(
               child: Text('Open Browser'), 
               onPressed: () => MyBrowser().openBrowser("https://flutter.dev"), 
            ),
         ), 
      ); 
   }
}
  • Jalankan aplikasi dan klik tombol Open Browser dan lihat bahwa browser telah diluncurkan. Anda dapat melihat aplikasi Browser - Halaman beranda seperti yang ditunjukkan pada gambar di bawah ini -

Anda dapat melihat aplikasi Browser - Layar browser seperti yang ditunjukkan pada gambar di bawah ini -

  • Print
  •  Tambahkan Catatan
  •  Tandai halaman ini
  •  Laporan kesalahan
  •  Suggestions

Simpan Tutup