Trong Flutter có rất nhiều widget để trình bày lên màn hình nhưng để chúng hiển thị ở vị trí và kích thước mà chúng ta mong muốn thế nào thì viết này mình sẽ làm một cheat sheet về layout trong fluter các bạn tham khảo nhé:
Layout trong Flutter
Row and Column
MainAxisAlignment
Đối với Row/Column sử dụng MainAxisAlignment
để căn chỉnh nội dung dựa vào trục trục chính là main axis
mainAxisAlignment: MainAxisAlignment.start,
- Row:
- Column:
class RowCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), ], ), ); }
}
Ngược lại với start
là end
ta sẽ được như sau:
-
Row:
-
Column:
class ColumnCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), ], ), ); }
}
Để tạo khoảng cách giữa các widget trong column ta sử dụng các thuộc tính như spaceBetween
, spaceEvenly
, spaceAround
SpaceBetween: Đối với thuộc tính này sẽ tạo khoảng cách đều giữa các widget con nhưng widget con đầu tiên và cuối cùng sẽ nằm sát với border bên ngoài:
- Row:
Column:
SpaceEvenly: Với thuộc tính này sẽ tạo kkhoảng cách đều nhau giữa các widgets con cho dù kích thước của widget bên ngoài có lớn bao nhiêu đi chăng nữa.
-
Row:
-
Column:
SpaceAround: Thuộc này sẽ tạo 1 padding bao quanh từng widget con, tuỳ vào số lượng widget và kích thước của widget bên ngoài nó sẽ tự động tính toán khoảng trống bao quanh bên ngoài cho từng widget.
-
Row:
-
Column:
CrossAxisAlignment
Được sử dụng để chỉ định cách mà các widget con sẽ được bố trí trên trục cross, trên column là trục dọc còn row là trục nằm ngang
crossAxisAlignment: CrossAxisAlignment.start,
-
Row:
-
Column:
crossAxisAlignment: CrossAxisAlignment.end,
-
Row:
-
Column:
crossAxisAlignment: CrossAxisAlignment.center,
Center: Sẽ đưa toàn bộ widgets con bên trong ra giữa
-
Row:
-
Column:
class ColumnCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 100.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), ], ), ); }
}
MainAxisSize
Kích thước của widget bên ngoài
mainAxisSize: MainAxisSize.min,
-
Row:
-
Column:
mainAxisSize: MainAxisSize.max,
-
Row:
-
Column:
class RowCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( color: Colors.white, child: Row( mainAxisSize: MainAxisSize.max, children: [ Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), Image( image: AssetImage('images/a.png'), width: 50.0, ), ], ), ); }
}
Expanded
Expanded là widget tự động lấp đầy khoảng trống nội dung của Row/Column, trường hợp có nhiều widgets con thì nó sẽ tự động căn chỉnh đều nhau hoặc chúng ta cũng có thể sử dụng thuộc tính flex
để thiết lập tỉ lệ mà nội dung của widget con sẽ chiếm.
class RowExpandCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: Row( mainAxisSize: MainAxisSize.max, children: [ Expanded( flex: 1, child: Container( color: Colors.amber, height: 100, ), ), Expanded( flex: 2, child: Container( color: Colors.green, height: 100, ), ), Expanded( flex: 1, child: Container( color: Colors.amber, height: 100, ), ), ], ), ); }
}
Container
Container là một widget để chứa duy nhất 1 widget trong nó, widget này nếu không chứa widget con nào sẽ tự động có kích thước bằng kích thước của widget cha còn nếu có chứa widget con bên trong thì widget này sẽ tự dộng trim kích thước theo nội dung của widget con. Cái này giống với div
bên html.
- Không chứa bất kì widget con nào:
class ContainerCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( color: Colors.amber, ); }
}
- Chứa widget con:
class ContainerCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( color: Colors.amber, child: Text("I'm container"), ); }
}
SizedBox
SizedBox khá giống với Container tuy nhiên nó sẽ không thể thiết lập được các thuộc tính như padding
, margin
, color
class SizedBoxCheatSheet extends StatelessWidget { @override Widget build(BuildContext context) { return Container( child: SizedBox( width: 100, height: 100, child: ElevatedButton( child: Text("Button"), onPressed: () {}, ), ), ); }
}
SafeArea
Trường hợp chúng ta muốn nội dung widget không bị che đi bởi status bar của Android hay Notch iPhone thì đây là widget rất hữu ích