Google Flutter From Scratch: Grid, Daftar, dan Sumber Data
() translation by (you can also view the original English article)
Hampir setiap aplikasi seluler non-trivial saat ini cenderung memiliki daftar dalam layout nya. Itu karena menggunakan daftar yang dapat digulir sering kali merupakan cara paling mudah untuk menampilkan sejumlah besar barang serupa di layar kecil.
Kerangka Flutter menawarkan beberapa widget yang dapat Anda gunakan secara efisien, dan dengan kode minimal, buat dan tampilkan daftar tersebut. Dalam tutorial ini, saya akan menunjukkan cara menggunakannya dengan sumber data lokal dan jarak jauh.
1. Menampilkan Daftar yang Tidak Dapat Digulir
Jika Anda perlu menampilkan sejumlah kecil barang serupa, dan Anda yakin bahwa layar pengguna akan dapat mengakomodasi semuanya pada saat yang sama, menggunakan widget Column
adalah hal yang paling efisien untuk dilakukan.
Untuk membuat daftar di aplikasi Flutter Anda, Anda dapat menggunakan List
class yang ditawarkan oleh bahasa pemrograman Dart. Setelah membuat daftar, Anda bisa menggunakan metode add ()
untuk menambahkan sejumlah item ke dalamnya. Kode berikut menunjukkan kepada Anda cara membuat daftar yang berisi tiga widget RaisedButton
:
1 |
// Create list
|
2 |
List<RaisedButton> myItems = new List(); |
3 |
|
4 |
// Add three button widgets to it
|
5 |
myItems.add(new RaisedButton( |
6 |
child: new Text("Twitter"), |
7 |
onPressed: (){} |
8 |
));
|
9 |
myItems.add(new RaisedButton( |
10 |
child: new Text("Facebook"), |
11 |
onPressed: (){} |
12 |
));
|
13 |
myItems.add(new RaisedButton( |
14 |
child: new Text("Reddit"), |
15 |
onPressed: (){} |
16 |
));
|
Perhatikan bahwa setiap item dalam daftar memiliki onPressed
event handler yang kosong terkait dengan itu karena, tanpa itu, item tersebut akan dinonaktifkan.
Sekarang daftar sudah siap, Anda dapat langsung menetapkannya ke children
property dari widget Column
yang akan ditampilkan. Biasanya, bagaimanapun, Anda juga akan ingin menentukan di mana daftar item harus ditempatkan di layar. Karena widget Column
adalah widget fleksibel, Anda dapat mengontrol posisi item di sepanjang sumbu utamanya dan sumbu silang menggunakan properti mainAxisAlignment
dan crossAxisAlignment
. Secara default, untuk widget Column
, sumbu utama adalah sumbu vertikal, dan sumbu silang adalah sumbu horizontal.
Kode berikut menunjukkan kepada Anda bagaimana meregangkan tiga tombol di sumbu horizontal dan menempatkannya di tengah layar secara vertikal:
1 |
Column column = new Column( |
2 |
mainAxisAlignment: MainAxisAlignment.center, |
3 |
crossAxisAlignment: CrossAxisAlignment.stretch, |
4 |
children: myItems |
5 |
);
|
Inilah yang akan terlihat seperti kolom sekarang:



Penting untuk dicatat bahwa Anda akan mengalami kesalahan runtime jika widget Column
tidak dapat mengakomodasi semua anak-anaknya. Misalnya, jika Anda memiliki lebih dari selusin widget RaisedButton
di daftar Anda, bukan tiga, Anda akan melihat pesan kesalahan yang terlihat seperti ini:



2. Menampilkan Daftar Digulir Sederhana
Untuk daftar yang sedikit lebih besar, daftar yang kontennya cenderung overflow the screen, Anda harus mempertimbangkan menggunakan widget ListView
karena mendukung pengguliran.
Anda mungkin telah memperhatikan bahwa kode yang kita tulis untuk membuat daftar pada langkah sebelumnya adalah panjang dan berulang. Membuat daftar yang lebih besar menggunakan pendekatan yang sama bisa sangat membosankan. Pendekatan alternatif yang mudah adalah menggunakan dua daftar sebagai gantinya: satu berisi data, dan satu berisi widget.
Berikut adalah bagaimana Anda dapat menggunakan operator []
untuk dengan cepat menciptakan daftar data, yang, untuk saat ini, hanya berisi beberapa string:
1 |
List<String> data = <String>["Twitter", "Reddit", "YouTube", "Facebook", |
2 |
"Vimeo", "GitHub", "GitLab", "BitBucket", "LinkedIn", "Medium", |
3 |
"Tumblr", "Instagram", "Pinterest"]; |
Untuk mengkonversi daftar string di atas ke dalam daftar widget RaisedButton
, Anda dapat menggunakan metode map ()
dan toList ()
. Dengan metode map ()
, Anda dapat menggunakan setiap string untuk menghasilkan widget RaisedButton
baru. Dan dengan metode toList ()
, Anda dapat mengonversi objek Iterable
yang dikembalikan oleh metode map ()
ke dalam objek List
sebenarnya. Kode berikut menunjukkan kepada Anda bagaimana:
1 |
List<RaisedButton> myWidgets = data.map((item) { |
2 |
return new RaisedButton( |
3 |
child: new Text(item), |
4 |
onPressed: () async { |
5 |
String url = "https://${item}.com"; |
6 |
if(await canLaunch(url)) |
7 |
await launch(url); |
8 |
}
|
9 |
);
|
10 |
}).toList(); |
Demi kelengkapan, kode di atas juga menunjukkan Anda bagaimana untuk membuat sebuah onPressed
event handler yang menggunakan metode canLaunch()
dan launch()
yang ditawarkan oleh paket url_launcher
untuk membuka situs web pengguna yang dipilih dalam default browser.
Setelah daftar Anda siap, Anda dapat meneruskannya ke children
property dari widget ListView
untuk menampilkannya.
1 |
ListView myList = new ListView( |
2 |
children: myWidgets |
3 |
);
|
Pada titik ini, jika Anda menjalankan aplikasi, Anda harus dapat menggulir daftar dan menekan tombol apa pun untuk meluncurkan situs web terkait.



3. Membuat Grid
Widget ListView
memungkinkan Anda menempatkan hanya satu item pada sumbu silangnya. Item akan, secara default, ditarik untuk menempati semua ruang yang tersedia pada sumbu itu. Jika Anda menginginkan lebih banyak fleksibilitas, Anda harus mempertimbangkan menggunakan widget GridView
sebagai gantinya, yang memungkinkan Anda menentukan berapa banyak item yang Anda inginkan di sumbu silang.
Kode berikut menggunakan konstruktor GridView.count ()
untuk membuat widget GridView
yang menampilkan dua item per baris:
1 |
GridView myGrid = GridView.count( |
2 |
crossAxisCount: 2, |
3 |
children: myWidgets |
4 |
);
|
Berikut adalah apa yang tampak seperti grid:



4. Menampilkan Daftar Besar
Untuk daftar data yang berisi lebih dari beberapa lusin item, Anda harus menghindari membuat daftar widget secara manual, seperti yang Anda lakukan pada langkah sebelumnya. Mengapa? Karena membuat widget adalah operasi yang mahal, dan daftar besar widget dapat menghabiskan banyak memori.
Sebagai gantinya, Anda harus menggunakan fungsi IndexedWidgetBuilder
, yang memungkinkan Anda menghasilkan widget hanya ketika pengguna perlu melihatnya. Dengan itu, Anda dapat dengan malas menghasilkan widget saat pengguna menggulir melalui widget ListView
Anda.
Sangat tidak mungkin bahwa Anda akan memiliki sejumlah besar data yang ditentukan tepat di dalam aplikasi Anda. Biasanya, Anda akan mengambil data tersebut dari server jauh. Oleh karena itu, untuk memberi Anda contoh realistis, izinkan saya sekarang menunjukkan kepada Anda cara mengambil 100 pertanyaan dari Stack Overflow menggunakan API Stack Exchange dan menampilkannya sesuai permintaan.
Mulailah dengan membuat subkelas dari kelas StatefulWidget
, yang akan bertindak sebagai kontainer untuk widget ListView
Anda dan menimpa metode createState ()
.
1 |
class VeryLargeListHolder extends StatefulWidget { |
2 |
@override
|
3 |
State<StatefulWidget> createState() { |
4 |
return new MyState(); |
5 |
}
|
6 |
}
|
Kelas MyState
yang disebutkan dalam kode di atas belum ada, jadi buat dan ganti metode build ()
-nya.
1 |
class MyState extends State<VeryLargeListHolder> { |
2 |
@override
|
3 |
Widget build(BuildContext context) { |
4 |
// TODO
|
5 |
}
|
6 |
}
|
Selanjutnya, tambahkan objek List
sebagai salah satu variabel anggota kelas. Anda akan menggunakannya untuk menyimpan pertanyaan yang Anda unduh dari Stack Overflow. Selain itu, tambahkan API's endpoint sebagai variabel lain.
1 |
List questions; |
2 |
|
3 |
String endpoint = "https://api.stackexchange.com/2.2/questions?" + |
4 |
"pagesize=100&order=desc&sort=activity&site=stackoverflow"; |
Kecuali Anda ingin pengguna Anda menekan tombol untuk mengunduh pertanyaan, saya sarankan Anda mengunduhnya secara otomatis ketika widget tersebut menginisialisasi. Dengan demikian, mengganti metode initState ()
dan membuat panggilan ke metode asinkron baru yang disebut loadData ()
.
1 |
@override
|
2 |
void initState() { |
3 |
super.initState(); |
4 |
loadData(); |
5 |
}
|
6 |
|
7 |
void loadData() async { |
8 |
// More code here
|
9 |
}
|
Di dalam metode loadData ()
, Anda dapat menggunakan fungsi get ()
dari paket http
Dart untuk mengunduh pertanyaan. API endpoint mengembalikan dokumen JSON, yang dapat Anda uraikan dengan menggunakan fungsi json.decode ()
yang tersedia dalam paket Dart's convert
. Kode berikut menunjukkan kepada Anda bagaimana:
1 |
String rawData = (await http.get(endpoint)).body; |
2 |
Map jsonData = json.decode(rawData); |
Setelah dokumen JSON diubah menjadi objek Map
, Anda dapat menggunakan nilai yang terkait dengan kunci items
untuk menginisialisasi questions
variable. Variabel, bagaimanapun, adalah bagian dari widget's state. Oleh karena itu, Anda harus memastikan Anda memperbaruinya di dalam metode setState ()
saja. Begini caranya:
1 |
setState(() { |
2 |
questions = jsonData["items"]; |
3 |
});
|
Pada titik ini Anda dapat membuat widget ListView
baru menggunakan konstruktor ListView.builder ()
, yang mengharapkan fungsi IndexedWidgetBuilder
dan jumlah item sebagai argumennya. Untuk saat ini, jumlah item tidak lain hanyalah ukuran daftar questions
. Dengan demikian, tambahkan kode berikut di dalam metode build ()
dari MyState
class:
1 |
ListView myList = ListView.builder( |
2 |
itemCount: questions == null ? 0 : questions.length, |
3 |
itemBuilder: (BuildContext context, int index) { |
4 |
// More code here
|
5 |
}
|
6 |
);
|
Dalam fungsi builder, yang perlu Anda lakukan adalah membuat pohon kecil widget untuk menampilkan berbagai informasi tentang setiap pertanyaan yang Anda download. Paket Flutter's material
menawarkan sebuah widget yang sangat berguna disebut ListTile
, yang memungkinkan Anda untuk dengan cepat menciptakan sebuah pohon sementara mengikuti pedoman desain bahan.
Kode berikut menunjukkan kepada Anda cara menampilkan judul pertanyaan dan penulis, menggunakan properti title
dan subtitle
dari widget ListTile
:
1 |
return new ListTile( |
2 |
title: Text(questions[index]["title"]), |
3 |
subtitle: Text("Asked by ${questions[index]["owner"]["display_name"]}") |
4 |
);
|
Terakhir, buat widget Scaffold
baru, tetapkan widget ListView
ke body
property, dan kembalikan dari metode build ()
sehingga dapat digunakan dengan widget MaterialApp
. Opsional, Anda dapat menambahkan widget AppBar
ke widget Scaffold
.
1 |
return new Scaffold( |
2 |
appBar: new AppBar( |
3 |
title: new Text("LargeListDemo") |
4 |
),
|
5 |
body: myList |
6 |
);
|
Inilah yang akan terlihat setelah aplikasi mengunduh pertanyaan:



Kesimpulan
Anda sekarang tahu cara bekerja dengan daftar dalam aplikasi Flutter. Dalam tutorial ini, Anda belajar tidak hanya cara membuat daftar dan kisi yang mendukung sumber data besar, tetapi juga cara membuat setiap item di dalamnya interaktif. Untuk mempelajari lebih lanjut tentang daftar di Flutter, Anda dapat merujuk ke documentation resmi.