Tutorial Flutter — Cara Menggunakan List View dan Page View

Belajar Flutter menggunakan List View dan Page View

Jeremia Manogi Mario
Komunitas Android  CCIT-FTUI
9 min readNov 3, 2019

--

Halo semua, Jeremy disini, dan pada kali ini saya akan berbagi insight mengenai List view dan ViewPage pada Flutter. Pertama, biarkan saya menjelasakan kelebihan dari list view daripada widget layout yang lain.

Pengertian ListView

Listview, tidak memiliki batasan dalam menaruh widget di dalamnya. Jika ada banyak widget di dalam list view yang sampai membuatnya melebihi layar handphone, secara otomatis listview akan memanjangakan layar (menggunakan scroll) sesuai banyak widget.

Kembali lagi ke project login kita sebelumnya. Kemudian kita buat file dart baru yang diberi nama listView.dart, dan mengisinya dengan class Statefull widget. Nama classnya akan diisi dengan List_View.

Membuat File Baru
Beri nama listView.dart
List_View class pada listView.dart

Sebelum kita memulai membuat class List_View, kita buat lagi file dart baru dan beri nama page_slash.dart. Setelah itu kita membuat class stateless. Isi saja namanya Page_Slash, kemudian kita buat class ini mengembalikan widget PageView. Syntaxnya Seperti dibawah ini:

import 'package:flutter/material.dart';

class Page_Slash extends StatelessWidget {
final String name, password;
Page_Slash(this.name,this.password);

final controller = PageController(initialPage: 0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home page")),
body: PageView(
controller: controller,
children: <Widget>[
Newpages("${name}","${password}")],
List_View(),
)
);
}
}

Pengertian PageView:

PageView seperti namanya, adalah widget yang digunakan untuk menaruh banyak class widget lainnya (stateless dan stateful), dan menarunya di halaman berbeda. User hanya perlu menggeser layarnya untuk berpindah dari satu class widget ke class widget lain, dan disini kita juga menambahkan constructor, mengapa? Akan dibahas setelah ini.

Kemudian kita buat variable PageController. PageController berfungsi untuk mengontrol PageView. PageController memungkinkan anda memanipulasi halaman mana yang terlihat dalam PageView. InitialPage berguna untuk menentukan halaman yang akan muncul terlebih dahulu. Perhitungannya sama seperti array, jadi halaman pertama dihitung sebagai 0 (nol).

Oh iya, sebelum itu kembali dulu ke firstPage.dart. Karena sekarang kita akan menggunakan PageView, maka kita ganti pada Navigator.push di tombol Sign In ke Page_Slash. Jangan lupa setelah menggantinya, tekan ctrl + titik (.) untuk menulis otomatis packagesnya.

Kembali kepertanyaan tadi, kenapa di class Page_Slash juga ditambahkan constructor? karena di dalam PageView kita akan menambah class NewPages, dan NewPages membutuhkan nilai di dalamnya karena class ini menggunakan constructor.

Jika sudah harusnya kalian sudah bisa menggeser layar kalian, dan halaman berikutnya pasti hitam. Nah, sekarang kita bisa membuat ListView kita. Format dari class ListView ini akan berisikan bio data kalian.

Seperti biasa, buat dulu filenya. Buat namanya kali ini listView.dart, dan kelasnya akan dibuat Stateful dengan nama List_View. Kemudian kalian bisa menambahkan variable. Variable yang dibutuhkan berisi nama kalian, Jenis kelamin, dan tempat dan tanggal lahir kalian.

import 'package:flutter/material.dart';class List_View extends StatefulWidget {@override
_List_ViewState createState() => _List_ViewState();
}
class _List_ViewState extends State<List_View> {
String text = "Jeremia Manogi Mario";
String tl = "Jakarta";
String ttl = "21 Desember 2000";
String gender = "Laki - laki";
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
]);
}
}

Disini kita akan mengganti Containernya dengan ListView. Pada widget pertama yang akan kita masukkan, adalah container yang berisi foto profil, dan biodata singkat dari variable yang telah kalian masukkan.

.............................................
Container(
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CircleAvatar(
radius: 45,
backgroundImage:
ExactAssetImage('assets/profil.png', scale: 2),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[

],
),]),
),
....................

Untuk Foto profilnya, akan kita pasang menggunakan widget CircleAvatar. Dan setelah itu, kita menambahkan Column untuk menaruh variable biodata, dan untuk setiap Text, kita akan menggunakan Kembali widget RichText. Sengaja ditambahkan Container di setiap RichText untuk memberikan padding.

.....................................
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 30, top: 10),
child: RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: "Nama : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: text,
style: TextStyle(fontWeight: FontWeight.bold)),
], style: TextStyle(fontSize: 14,color:Colors.black)),
)),
Container(
margin: EdgeInsets.only(right: 30),
child: RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: "Tempat/Tanggal Lahir : \n",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: "${tl}/${ttl}",
style: TextStyle(fontWeight: FontWeight.bold)),
], style: TextStyle(fontSize: 14,color: Colors.black)),
)),
Container(
margin: EdgeInsets.only(right: 30),
child: RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: "Jenis Kelamin : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: gender,
style: TextStyle(fontWeight: FontWeight.bold)),
], style: TextStyle(fontSize: 14,color: Colors.black)),
)),
],
)

Kemudia kita akan membuat widget Card untuk tempat mengisi alamat. Sebelum itu, kita kembali ke atas, bagian variable tadi untuk menambah variable alamat. Kali ini kita akan menggunakan Map.

.............
class _List_ViewState extends State<List_View> {
String text = "Jeremia Manogi Mario";
String tl = "Jakarta";
String ttl = "21 Desember 2000";
String gender = "Laki - laki";

Map<String, String> alamat = {
"alamat": "Jln.Pegawai Solo",
"rt/rw": "001/013",
"kel/Desa": "SUKAMAJU BARU",
"kec": "Tapos"
};
............

Map

Map, sebuah sebuah tipe variable yang menggunakan kunci (key) dan nilai (value). Kurang lebih Map sama seperti array object pada Java dan cara membuatnya tidak jauh beda dengan membuat variable biasa. Hanya saja, ketika kita menggunakan map akan terlihat lebih terkelompok. Kunci/key (pada bagian kiri) bisa disebut dengan “variable” di dalam kelompok yang kalian buat, dan nilai/value(pada bagian kanan) tentu saja nilai untuk key tersebut.

Jika pada variable kita tidak bisa membuat nama variable yang sama, tapi kita bisa mendekrasikan nilai yang sama pada variable yang berbeda. Sama seperti Map, kita tidak bisa membuat 2 nama key yang sama, tapi kita bisa membuat value yang sama di key yang berbeda.

Ada 2 bentuk deklarasi map. Pertama menggunakan constructor, dan yang ke-2 menggunakan riteral.

Kiri literal, dan kanan constructor

Tidak ada yang berbeda dari fungsi keduanya. Hanya saja literal, bisa langsung di isi/memberikan nilai di dalam atau diluar Widget builde. Sedangkan constructor, hanya bisa memberikan nilai di dalam Wiget builde walau kita bisa mendeklarasikan variablenya di luar.

Pada syntax di atas, kita mendeklarasikan variable “alamat” dengan tipe variable map. Didalamnya terdapat key(alamat, rt/rw, kel/Desa, kec) dan value(Jln.Pegawai Solo, 001/013, SUKMAJU BARU, Tapos).

Jika sudah, kita kembali lagi ke bawah untuk menambahkan Card nya.

...............................
Container(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Card(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 3.5),
height: 100,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
text: TextSpan(
style: TextStyle(fontSize: 14, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: "Alamat : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: alamat["alamat"],
style: TextStyle( fontStyle: FontStyle.italic,
decoration: TextDecoration.underline)),
]),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 14, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: "RT/RW : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: alamat["rt/rw"],
style: TextStyle( fontStyle: FontStyle.italic,
decoration: TextDecoration.underline)),
]),
),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 14, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: "keluran/Desa : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: alamat["kel/Desa"],
style: TextStyle(fontStyle: FontStyle.italic,
decoration: TextDecoration.underline)),
]),
),
RichText(
text: TextSpan(
style: TextStyle(
fontSize: 14, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: "kecamatan : ",
style: TextStyle(fontStyle: FontStyle.italic)),
TextSpan(
text: alamat["kec"],
style: TextStyle(
fontStyle: FontStyle.italic,
decoration:TextDecoration.underline)),
]),
)
],
),
)
],
)),
),
)
..................................

Dan disini cara memanggil value dari map. Dengan menulis nama variable map tersebut, kemudia menuliskan nama key nya di dalam kurung siku.

Contohnya seperti ini.

text: alamat["alamat"],

Jika dijalankan, yang muncul baru seperti ini.

Catatan:

kita bisa menuliskan key pada Map seperti ini: “alamat.keys.elementAt(0)”
Artinya dari syntax/baris ini adalah key dari alamat pada baris/key pertama diambil .
Jadi alamat[“alamat”] bisa ditulis alamat[alamat.key.elementAt(0)]

Selanjutanya kita akan membuat ListView.builder. Apa yang berbeda dari ListView biasa? ListView.builder dapat menggandakan widget dari satu widget saja, sesuai dengan kebutuhan. Jatuhnya seperti kita membuat widget dengan looping menggunakan foreach, dan ListView.builder ini, yang paling sering digunakan untuk membuat list.

Teori dasar ListView builder

Inilah persamaan for looping dengan ListView.builder. Inisialisasi di ListView, akan selalu 0. Untuk membuat kondisi kapan ListView.builder berhenti, isikan didalam itemCount. Dan ListView.builder, akan selalu melakukan increment looping (dari kecil ke besar).

Pada ListView.builder, kita akan membuat daftar no telephone. Contoh yang akan kita buat seperti ini.

Pertama , kita buat dulu kelas baru. Kali ini, kita akan membuat widget di layar yang sama tapi di kelas dan file yang berbeda. Buat saja nama filenya scroll_tilelist.dart, dan nama kelasnya Tile_Listing. Buat saja dengan tipe Stateless.

Lalu kita buat Constructor untuk kelas ini. Kita akan menambahkan 3 variable List untuk constructor ini. List singkatnya sama seperti array yang ada di bahasa pemogramman lainnya. Tambahkan variable dan constructornya seperti di bawah ini.

class Tile_Listing extends StatelessWidget {final List<String> images;
final List<String> title;
final List<String> phones;
Tile_Listing({this.images,this.title,this.phones});..................

Ketiga variable ini akan menyimpan gambar, nama dan no telephone. Sekarang kita akan menambahkan panjang dan lebar untuk Widget satu ini. Tambahkan snytax ini dibawah container:

..........................................................
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 2,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 1),
.................................................................

MediaQuery

MediaQuery adalah widget untuk menampilkan informasi penting dari mobile kalian seperti ukuran layar, default padding layar, orientation layar, dan lain — lain. Singkatnya kalian bisa menggunakan MediaQuery agar aplikasi kalian bisa responsive pada segala device.

Contohnya pada syntax di atas, kita mengambil ukuran lebar device mobile kalian dan menjadikannya lebar pada widget ListView.builder . Untuk tingginya, kita bagi saja menjadi dua agar tidak terlalu tinggi. Sekarang kita tambah ListView.builder nya.

child: ListView.builder(
itemCount: images.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 10.0,
child: ListTile(
leading: CircleAvatar(
radius: 30,
backgroundImage: ExactAssetImage(images[index]),
),
title: Text(title[index], style: TextStyle(fontSize: 14)),
subtitle: Text(phones[index], style: TextStyle(fontSize: 10)),
trailing: Icon(Icons.tag_faces),
),
);
},));

Di ListView.builder ini, kita akan membuat setiap daftar menggunakan ListTile. Setelah selesai, kita kembali listView.dart. Sekarang, kita deklarasikan 3 List untuk widget ListView.builder yang tadi kita buat. Dan terserah kalian ingin mengisinya apa. Tapi pastikan jumlah dari setiap list sama.

final List<String> myList = [
'assets/banner1.jpg',
'assets/banner2.jpg',
'assets/banner3.jpg',
'assets/banner4.jpg',
'assets/banner5.jpg',
];
final List<String> names = ['ichigo', 'niigo', 'sango', 'yongo', 'hakko'];final List<String> phones = [
'(021)678392',
'(021)678334',
'(021)672414',
'(021)678390',
'(021)679992'
];

Lalu kita tambahkan widget Text dan ListView.builder yang telah kita buat. Cara memanggil ListView.builder-nya dengan memanggil kelasnya, dan mengisi constructornya.

...................
Container(
padding: EdgeInsets.symmetric(horizontal: 20.0,vertical: 14.0),
child: Text(
'Kontak teman mu: ',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w600,
),
),
),
Tile_Listing(
images: myList,
title: names,
phones: phones,
)
....................

ListView juga bisa diatur horizontal, seperti contoh di bawah ini.

Kita buat lagi file baru. Buat saja nama filenya scroll_horizontal.dart . Dan ketik syntax dibawah ini.

import 'package:flutter/material.dart';class ContentScroll extends StatelessWidget {
final List<String> images;
ContentScroll({
this.images,
});
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 3,
child: ListView.builder(
padding: EdgeInsets.symmetric(vertical: 20.0),
scrollDirection: Axis.horizontal,
itemCount: images.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(left: 10, right: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.black54,
offset: Offset(0.0, 4.0),
blurRadius: 6.0,
)],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset(
this.images[index],
width: 200,
height: 210,
fit: BoxFit.cover,
),
),
);
},
));
}
}

Yang membuat ListView menjadi horizontal, adalah pada scrollDirection -nya.

scrollDirection: Axis.horizontal,

Secara default, scrollDirection pada ListView akan terisi vertical. Untuk membuatnya horizontal, kita perlu menggantinya dan karena kita akan menggunakan gambar, kita akan menggunakan widget ClipRect. Ini sama seperti container, tapi ini khusus untuk gambar dan widget sejenisnya.

Jika sudah, kembali lagi ke file listView.dart . Tambahkan syntax ini:

ContentScroll(
images: myList,
)

Kalian bisa membuat List baru untuk membuat daftar gambar baru, atau menggunakan List gambar yang tadi. Itu Terserah.

Setelah itu run. Harusnya tampilannya seperti ini.

Terima kasih karena telah menyempatkan waktu anda untuk membaca artikel ini. Belajar Flutter memang sulit-sulit mudah, tapi jika anda telah terbiasa tentu saja tidak akan sulit. Semangat selalu semoga perlahan kemampuan kalian dapat meningkat lebih baik!

Kurang lebihnya mohon maaf. Terima kasih.

--

--