Membuat Web Menggunakan Flutter? Kenalan Yuk Dengan Hummingbird
Pengertian Hummingbird
Pada bulan Desember 2018, Google sebagai pengembang Flutter mengumumkan versi yang dapat di jalankan sebagai sebuah web atau yang disebut dengan proyek Hummingbird. Pada acara Google IO 2019, diumumkan kabar baik tentang rilisnya Flutter Web versi technical preview dari project Flutter Hummingbird.
Humminbird memiliki sebuah arsitektur seperti yang di bawah ini :
Bisa dilihat untuk menjalankan proyek Flutter sebagai sebuah website, dibutuhkan core atau inti dari Flutter untuk melakukan drawing pada lapisan teratas standar browser API. Menggunakan kombinasi dari DOM, Canvas, dan CSS, Flutter dapat menyediakan sebuah sistem yang memiliki kualitas tinggi, portable dan pengalaman pengguna pada setiap browser modern.
Secara teknis, dibutuhkan kompiler khusus untuk melakukan kompilasi inti dari Flutter dan framework yang berada di dalam project ke dalam sebuah berkas tunggal yang dapat di-deploy ke web server apapun.
Prinsip Kerja Flutter Web
Prinsip kerja Flutter Mobile dan Desktop, yaitu :
Secara garis besar hanya perlu fokus pada bagian paling atas saja. Bagian itu merupakan kode-kode program dari aplikasi. Kemudian yang di bawahnya merupakan Flutter Engine untuk membangun aplikasi kita.
Jadi bisa disimpulkan :
- Ngoding menggunakan bahasa pemrograman Dart.
- Flutter akan build ke platform yang dituju menggunakan enginenya.
Sedangkan tugas dari platform-spesific embeder yaitu membungkus aplikasi yang dibuat agar bisa dijalankan di berbagai platform seperti Linux, Windows, Mac OS, dan Google Chrome.
Kasus di atas hanya fokus ke Flutter Desktop, gimana kalau Flutter Web mirip ?
Flutter menggunakan Dart2js untuk mengcompile script yang dibuat di Flutter ke Javascript. Sehingga, Flutter dapat dijalankan pada browser.
Alurnya seperti dibawah ini :
Proyek Web Flutter
Sebelum membuat proyek perlu mengaktifkan terlebih dahulu fitur web untuk Flutter. Karena untuk saat ini, fitur tersebut masih dalam tahap pengembangan. Artinya perlu berpindah dari channel stable ke channel beta. Berikut langkah-langkahnya :
- Buka terminal atau command prompt dan jalankan perintah berikut untuk berpindah dari channel stable ke channel beta :
1
flutter channel beta
- Jika tidak terdapat eror, lanjutkan dengan perintah berikut untuk upgrade Flutter SDK :
1
flutter upgrade
- Setelah selesai bisa langsung mengaktifkan fitur dukungan web dengan perintah berikut :
1
flutter config --enable-web
- Untuk memastikan apakah fitur dukungan web sudah aktif, jalankan perintah flutter devices pada terminal. Dapat melihat beberapa perangkat yang terkoneksi untuk digunakan seperti berikut :
1 2 3 4
2 connected device: Web Server • web-server • web-javascript • Flutter Tools Chrome • chrome • web-javascript • Google Chrome 81.0.4044.129
Sampai saat ini sudah bisa membuat proyek baru seperti biasanya dan menjalankannya langsung pada browser. Jalankan perintah berikut pada terminal untuk mencobanya :
1 |
flutter run -d chrome |
Tunggu hingga proses kompilasi selesai dan jendela baru chrome terbuka. Kurang lebih akan seperti ini tampilannya:
Responsive Widget
Dalam mengembangkan sebuah website, salah satu yang perlu diperhitungkan adalah seberapa responsive website tersebut terhadap perubahan yang terjadi khususnya pada perubahan tampilan. Lalu bagaimana memenuhi kebutuhan tersebut pada proyek Flutter yang notabene. Serahkan semuanya pada widget MediaQuery dan LayoutBuilder!
Membuat kelas helper yang akan menampung beberapa informasi terkait ukuran lebar browser seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import 'package:flutter/material.dart'; class ScreenHelper { static bool isSmallScreen(BuildContext context) { return MediaQuery.of(context).size.width <= 600; } static bool isNormalScreen(BuildContext context) { return MediaQuery.of(context).size.width > 600 && MediaQuery.of(context).size.width <= 900; } static bool isMediumScreen(BuildContext context) { return MediaQuery.of(context).size.width > 900 && MediaQuery.of(context).size.width <= 1300; } static bool isLargeScreen(BuildContext context) { return MediaQuery.of(context).size.width > 1300; } static String screenType(BuildContext context) { if (isSmallScreen(context)) return "Small Screen"; if (isNormalScreen(context)) return "Normal Screen"; if (isMediumScreen(context)) return "Medium Screen"; if (isLargeScreen(context)) return "Large Screen"; return "undefined"; } }
|
Jika diperhatikan setiap fungsi yang pada kode di atas terdapat penggunaan MediaQuery untuk mendapatkan informasi ukuran lebar browser dan disesuaikan dengan ketentuan ukuran responsive.
Membuat custom widget GridView dimana gridCount-nya akan menyesuaikan masing-masing ukuran responsive. Dimulai dengan membuat berkas Dart baru dan lengkapi kodenya seperti di bawah ini :
1 2 3 4 5 6 7 8 9 10 |
class GridViewResponsive extends StatefulWidget { @override _GridViewResponsiveState createState() => _GridViewResponsiveState(); } class _GridViewResponsiveState extends State<GridViewResponsive> { @override Widget build(BuildContext context) { return Container(); } |
Fokus pada kelas GridViewResponsive, tambahkan beberapa properti ukuran dan daftar widget yang akan disematkan pada properti children dari widget GridView seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 |
class GridViewResponsive extends StatefulWidget { final List<Widget> children; final int smallScreenGridCount; final int normalScreenGridCount; final int mediumScreenGridCount; final int largerScreenGridCount; @override _GridViewResponsiveState createState() => _GridViewResponsiveState(); } |
Maka akan mendapati eror di beberapa properti yang sudah ditambahkan. Mengatasinya dengan menambahkan constructor untuk menetapkan nilai dari beberapa properti tersebut seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class GridViewResponsive extends StatefulWidget { final List<Widget> children; final int smallScreenGridCount; final int normalScreenGridCount; final int mediumScreenGridCount; final int largerScreenGridCount; const GridViewResponsive( {Key key, this.smallScreenGridCount, this.normalScreenGridCount, this.mediumScreenGridCount, this.largerScreenGridCount, @required this.children}) : super(key: key); @override _GridViewResponsiveState createState() => _GridViewResponsiveState(); } |
Fokus pada kelas _GridViewResponsiveState. Di sini akan menyesuaikan sedikit kode didalamnya dengan menggunakan widget LayoutBuilder dan GridView tentunya. Ubah isi dari fungsi build() menjadi seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class _GridViewResponsiveState extends State<GridViewResponsive> { @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { int gridCount = 2; return GridView.count( crossAxisCount: gridCount, children: widget.children, ); }); } } |
GridCount masih bernilai statis yang artinya tidak dapat menyesuaikan perubahan yang berakibat tidak responsive-nya halaman. Lantas bagaimana menentukan nilainya agar bisa dinamis? Bisa menggunakan cara tradisional yaitu dengan menentukannya menggunakan if statement seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class _GridViewResponsiveState extends State<GridViewResponsive> { @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { int gridCount = 2; if (constraints.maxWidth <= 600) { gridCount = widget.smallScreenGridCount ?? 2; } else if (constraints.maxWidth > 600 && constraints.maxWidth <= 900) { gridCount = widget.normalScreenGridCount ?? 4; } else if (constraints.maxWidth > 900 && constraints.maxWidth <= 1200) { gridCount = widget.mediumScreenGridCount ?? 6; } else { gridCount = widget.largerScreenGridCount ?? 8; } return GridView.count( crossAxisCount: gridCount, children: widget.children, ); }); } } |
Berkas Dart yang sudah disesuaikan kode di dalamnya akan seperti di bawah ini :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import 'package:flutter/material.dart'; class GridViewResponsive extends StatefulWidget { final List<Widget> children; final int smallScreenGridCount; final int normalScreenGridCount; final int mediumScreenGridCount; final int largerScreenGridCount; const GridViewResponsive( {Key key, this.smallScreenGridCount, this.normalScreenGridCount, this.mediumScreenGridCount, this.largerScreenGridCount, @required this.children}) : super(key: key); @override _GridViewResponsiveState createState() => _GridViewResponsiveState(); } class _GridViewResponsiveState extends State<GridViewResponsive> { @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { int gridCount = 2; if (constraints.maxWidth <= 600) { gridCount = widget.smallScreenGridCount ?? 2; } else if (constraints.maxWidth > 600 && constraints.maxWidth <= 900) { gridCount = widget.normalScreenGridCount ?? 4; } else if (constraints.maxWidth > 900 && constraints.maxWidth <= 1200) { gridCount = widget.mediumScreenGridCount ?? 6; } else { gridCount = widget.largerScreenGridCount ?? 8; } return GridView.count( crossAxisCount: gridCount, children: widget.children, ); }); } } |
Menggunakan Responsive Widget
Menyesuaikan terlebih dahulu kelas main.dart menjadi seperti di bawah ini :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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( // is not restarted. primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Grid Responsive'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('${widget.title} [${ScreenHelper.screenType(context)}]'), ), body: Container(), // This trailing comma makes auto-formatting nicer for build methods. ); } } |
Menambahkan data dan daftar widget yang akan ditampilkan pada GridView. Fokus pada kelas _MyHomePageState kemudian tambahkan beberapa baris kode berikut :
1 2 3 4 5 6 7 8 9 |
class _MyHomePageState extends State<MyHomePage> { List<String> raw = "d, i, c, o, d, i, n, g".toUpperCase().split(","); List<Widget> gridWidget = []; @override Widget build(BuildContext context) { return Scaffold( … ); } } |
Setelah itu, override fungsi initState() untuk melakukan generate daftar widget berdasarkan data yang sudah ditambahkan seperti di bawah ini :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class _MyHomePageState extends State<MyHomePage> { List<String> raw = "d, i, c, o, d, i, n, g".toUpperCase().split(","); List<Widget> gridWidget = []; @override void initState() { super.initState(); List.generate( 50, (index) => gridWidget.add( Container( margin: EdgeInsets.all(8), color: Colors.blue, child: Center( child: Text( (raw.toList()..shuffle()).first, style: TextStyle(color: Colors.white, fontSize: 30), ), ), ), ), ); } @override Widget build(BuildContext context) { return Scaffold( ... ); } } |
Ubah kode yang berada di dalam fungsi build() dengan menggunakan custom widget yang sudah dibuat seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
class _MyHomePageState extends State<MyHomePage> { List<String> raw = "d, i, c, o, d, i, n, g".toUpperCase().split(","); List<Widget> gridWidget = []; @override void initState() { super.initState(); List.generate( 50, (index) => gridWidget.add( Container( margin: EdgeInsets.all(8), color: Colors.blue, child: Center( child: Text( (raw.toList()..shuffle()).first, style: TextStyle(color: Colors.white, fontSize: 30), ), ), ), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('${widget.title} [${ScreenHelper.screenType(context)}]'), ), body: Padding( padding: const EdgeInsets.all(8.0), child: GridViewResponsive( children: gridWidget, ), ), // This trailing comma makes auto-formatting nicer for build methods. ); } } |
Jika tidak terdapat eror saat kompilasi, tampilannya akan seperti di bawah ini :
Kelebihan Menggunakan Flutter
1. Kelebihan bagi developer
1. Fast Development
Flutter in-built fitur menggabungkan semua komponen untuk iOS dan Android untuk memberikan kinerja dasar native untuk aplikasi.
2. Single Codebase
Fitur basis kode tunggal membantu kita untuk membuat app dengan lebih cepat daripada pengembangan app native lainnya.
Sekarang dapat menulis satu basis kode untuk Android dan iOS yang menghemat banyak waktu dalam pengelolaan kode.
3. Hot Reload
Fitur ini membantu mendebug kode lebih cepat dibandingkan dengan pengembangan aplikasi native, jadi dapat terus menguji dan men-debugnya, dan membangun aplikasi yang bagus.
4. Expressive UI
Membangun UI yang ekspresif dengan Flutter material desain yang indah dan Widget Cupertino (rasa iOS), Rich Motion API, dan pengguliran alami yang halus.
Fitur bawaannya membantu mengembangkan cepat dengan widget yang sepenuhnya dapat disesuaikan yang dapat digunakan kembali, jika memerlukan penyesuaian lebih lanjut di masa mendatang.
5. Mudah dimengerti dan dipelajari
Bahkan bagi yang baru di Flutter bisa memahaminya dengan mudah. Jika sudah pernah menggunakan Java maka mungkin lebih mudah untuk memulai mengembangkan dengan Flutter.
Flutter menggunakan Dart, sebuah bahasa pemrograman berorientasi objek baru (dart.dev) yang mudah dipelajari dan dipahami. Dapat memulai pengaturan dan membuat aplikasi Flutter dari situs resmi Flutter (flutter.dev)
6. Komunitas yang berkembang
Flutter telah menjadi komunitas pengembangan yang paling berkembang di seluruh dunia dalam pengembangan aplikasi. Yang terus mendiskusikan fitur-fitur baru dan mengatasi bug saat mengembangkan aplikasi Flutter.
Dapat memposting pertanyaan di komunitas Flutter dev dan akan mendapatkan saran cepat dari pengembang Flutter di seluruh dunia dalam waktu yang singkat.
2. Kelebihan bagi pelanggan dan bisnis
1. Fast Development
Sama seperti kelebihan flutter bagi pengembang atau developer app, pengembangan yang cepat juga merupakan kelebihan bagi pelanggan dan bisnis.
2. Waktu dan Biaya
Yang tak kalah paling penting, Flutter akan menghemat biaya dan waktu. Tidak perlu tim pengembangan dan pengujian terpisah untuk platform iOS dan Android.
3. Pengelolaan Aplikasi
Dalam Flutter semuanya adalah widget. Jadi mudah untuk menyesuaikan dan Mengelola aplikasi. misalnya jika kami memerlukan penyesuaian berdasarkan pasar, maka mudah dan cepat untuk memperbarui dan mengelola aplikasi.
4. Pengelolaan Team
Dengan fitur bawaan pengembangan Flutter, hanya perlu satu tim pengembangan dan pengujian Flutter untuk mengembangkan dan mengelola aplikasi.
3. Perusahaan Besar Yang Menggunakan Flutter
1. Google
Google Ads dan Google Assistance telah dikembangkan dengan Flutter yang menyediakan user experience mendasar.
2. Alibaba
Alibaba adalah salah satu platform bisnis eCommerce terbesar. Alibaba telah menggunakan Flutter untuk pengembangan aplikasi mereka.