Flutter: LinearLayout
How to design LinearLayout in Flutter
Series
Introduction
Di Flutter, untuk membuat layout ada beberapa widget yang bisa kita pakai yaitu sebagai berikut.
- Row
- Column
- Container
- Expanded
- GridView
- ListView
- Stack
- Dan lain-lainnya bisa kita pelajari di dokumentasinya https://flutter.io/docs/development/ui/layout
Di Android, untuk membuat layout kita bisa pakai layout xml berikut.
- AbsoluteLayout (deprecated)
- LinearLayout
- RelativeLayout
- ScrollView
- FrameLayout
- CoordinatorLayout
- ConstraintLayout
Lalu, apakah kita bisa membuat LinearLayout seperti di Android pada Flutter? Jawabannya bisa. Adapun goal kita kali ini adalah kita bisa memahami cara kerja dari widget Row
, Column
, Container
, dan Expanded
. Dan berikut adalah output dari aplikasi yang akan kita buat pada artikel ini.
Row
Sebelum kita bisa membuat output Goal seperti diatas maka, kita perlu memahami cara kerja dari widget Row
. Widget Row
bekerja dimana, widget ini akan menyusun layout-nya dengan susunan horizontal. Contohnya seperti berikut.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Row"),
),
),
body: Row(
children: <Widget>[
Text("1", style: TextStyle(fontSize: 24)),
Text("2", style: TextStyle(fontSize: 24)),
Text("3", style: TextStyle(fontSize: 24)),
Text("4", style: TextStyle(fontSize: 24)),
Text("5", style: TextStyle(fontSize: 24))
],
),
),
));
Jadi, didalam widget Row
terdapat attribute children
dimana, didalamnya kita isi dengan widget Text
yang diberi style dengan fontSize
24.
Column
Widget ini berfungsi untuk membuat layout dalam susunan vertical. Silakan kita ubah kode kita sebelumnya menjadi seperti berikut.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Row"),
),
),
body: Column(
children: <Widget>[
Text("1", style: TextStyle(fontSize: 24)),
Text("2", style: TextStyle(fontSize: 24)),
Text("3", style: TextStyle(fontSize: 24)),
Text("4", style: TextStyle(fontSize: 24)),
Text("5", style: TextStyle(fontSize: 24))
],
),
),
));
Container
Widget Container
berfungsi untuk menampung widget lain dimana, dengan widget ini kita bisa menambahkan attribute padding
, margin
, color
dan lain sebagainya.
Sekarang coba kita ubah kode kita sebelumnya dengan cara menambahkan margin
pada Row
dan Column
lalu, kita tambahkan color
pada Row
dan Column
. Selanjutnya, kita tambahkan padding
dan color
pada widget Text
agar kelihatan sisi dari margin
dan padding
. Berikut untuk contoh penambahan Container
pada widget Row
.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Container And Row"),
),
),
body: Container(
margin: EdgeInsets.all(16),
padding: EdgeInsets.all(16),
color: Colors.green,
child: Row(
children: <Widget>[
Container(
color: Colors.red,
padding: EdgeInsets.all(16),
child: Text("1", style: TextStyle(fontSize: 24))),
Container(
color: Colors.yellow,
padding: EdgeInsets.all(16),
child: Text("2", style: TextStyle(fontSize: 24))),
Container(
color: Colors.purple,
padding: EdgeInsets.all(16),
child: Text("3", style: TextStyle(fontSize: 24))),
Container(
color: Colors.pink,
padding: EdgeInsets.all(16),
child: Text("4", style: TextStyle(fontSize: 24))),
Container(
color: Colors.lightBlue,
padding: EdgeInsets.all(16),
child: Text("5", style: TextStyle(fontSize: 24)))
],
),
),
),
));
Dari gambar diatas bisa kita lihat mana yang margin
dan padding
. Pada widget Container
yang ada didalam attribute body
dimana, margin
-nya yang jarak dari tepi layar ke kotak warna hijau dan padding
-nya yang jarak dari kotak warna hijau ke kotak warna nomor 1. Lalu, untuk setiap Container
disetiap item didalam children
yang mana jarak tulisan nomor menuju kotak luarnya disebut sebagai padding
. Berikut gambar penjelasannya.
Lalu, untuk Column
hasilnya akan menjadi seperti berikut.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Container And Row"),
),
),
body: Container(
margin: EdgeInsets.all(16),
padding: EdgeInsets.all(16),
color: Colors.green,
child: Column(
children: <Widget>[
Container(
color: Colors.red,
padding: EdgeInsets.all(16),
child: Text("1", style: TextStyle(fontSize: 24))),
Container(
color: Colors.yellow,
padding: EdgeInsets.all(16),
child: Text("2", style: TextStyle(fontSize: 24))),
Container(
color: Colors.purple,
padding: EdgeInsets.all(16),
child: Text("3", style: TextStyle(fontSize: 24))),
Container(
color: Colors.pink,
padding: EdgeInsets.all(16),
child: Text("4", style: TextStyle(fontSize: 24))),
Container(
color: Colors.lightBlue,
padding: EdgeInsets.all(16),
child: Text("5", style: TextStyle(fontSize: 24)))
],
),
),
),
));
Expanded
Widget Expanded
berfungsi untuk membuat widget child
-nya menjadi match_parent
atau memenuhi semua space yang kosong. Sekarang coba kita ubah kode sebelumnya agar setiap widget Text
width atau height-nya menjadi memenuhi sisa space baik secara horizontal maupun vertical. Berikut untuk yang Row
.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Container, Row, and Expanded"),
),
),
body: Container(
margin: EdgeInsets.all(16),
padding: EdgeInsets.all(16),
color: Colors.green,
child: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
padding: EdgeInsets.all(16),
child: Text("1", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.yellow,
padding: EdgeInsets.all(16),
child: Text("2", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.purple,
padding: EdgeInsets.all(16),
child: Text("3", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.pink,
padding: EdgeInsets.all(16),
child: Text("4", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.lightBlue,
padding: EdgeInsets.all(16),
child: Text("5", style: TextStyle(fontSize: 24))),
)
],
),
),
),
));
Dan berikut untuk widget Column
.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Container(
color: Colors.blue,
child: Text("Container, Column, and Expanded"),
),
),
body: Container(
margin: EdgeInsets.all(16),
padding: EdgeInsets.all(16),
color: Colors.green,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
padding: EdgeInsets.all(16),
child: Text("1", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.yellow,
padding: EdgeInsets.all(16),
child: Text("2", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.purple,
padding: EdgeInsets.all(16),
child: Text("3", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.pink,
padding: EdgeInsets.all(16),
child: Text("4", style: TextStyle(fontSize: 24))),
),
Expanded(
flex: 1,
child: Container(
color: Colors.lightBlue,
padding: EdgeInsets.all(16),
child: Text("5", style: TextStyle(fontSize: 24))),
)
],
),
),
),
));
Let’s Rock
Sekarang setelah kita memahami cara kerja dari widget Row
, Column
, Container
, dan Expanded
maka, saatnya kita buat aplikasi goal-nya. Silakan kita ketik kode-nya seperti berikut.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Container(
child: Text("LinearLayout",
style: TextStyle(color: Colors.black),
textAlign: TextAlign.center),
),
),
body: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.only(top: 16),
color: Colors.red,
child: Text("Merah",
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.only(top: 16),
color: Colors.green,
child: Text("Hijau",
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.only(top: 16),
color: Colors.blue,
child: Text("Biru",
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.only(top: 16),
color: Colors.yellow,
child: Text("Kuning",
style: TextStyle(color: Colors.black),
textAlign: TextAlign.center),
),
)
],
),
),
Expanded(
flex: 1,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Baris pertama",
style: TextStyle(fontSize: 48),
)
],
),
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Baris kedua",
style: TextStyle(fontSize: 48),
)
],
),
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Baris ketiga",
style: TextStyle(fontSize: 48),
)
],
),
),
Expanded(
flex: 1,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Baris keempat",
style: TextStyle(fontSize: 48),
)
],
),
)
],
),
)
],
),
),
));
Pada kode diatas sepertinya ada attribute yang belum saya jelaskan yaitu, mainAxisSize
dan crossAxisAlignment
dimana, sebenarnya mainAxisSize
berfungsi untuk menentukan size dari sebuah widget Row
dan Column
. Misalnya Row
dengan mainAxisSize.max
maka, size dari widget Row
akan menjadi penuh atau match_parent
secara horizontal. Namun, jika set mainAxisSize.min
maka, size dari widget Row
akan menjadi wrap_content
atau sesuai size dari content-nya. Begitu juga untuk widget Column.
Lalu, untuk attribute crossAxisAlignment
ini fungsinya hampir sama seperti mainAxisSize
hanya saja dia bersifat kebalikannya. Misal, Row
dengan CrossAxisAlignment.start
maka, posisinya akan berada diatas secara vertical. Lalu, jika Column
dengan CrossAxisAlignment.start
maka, posisinya akan berada disebelah kiri secara horizontal. Ingat bahwa attribute crossAxisAlignment
bersifat berlawanan dengan orientation si Row
dan Column
. Misal widget Row
orientation-nya horizontal maka, ketika diberi attribute crossAxisAlignment
maka, attribute crossAxisAlignment
akan ber-orientation vertical. Sama halnya dengan widget Column.