Linear, Relative, Constraint, Table, Frame và nhiều loại khác. Android cung cấp nhiều loại layout để thiết kế ứng dụng. Câu hỏi là: loại nào tốt nhất?
Trước khi đi vào chi tiết từng layout, chúng ta sẽ xem qua hệ thống phân cấp View và quá trình vẽ của Android.
View và ViewGroup
Hãy coi ViewGroup là lớp cha của mọi view và cũng là lớp cơ sở cho các layout. Nó đại diện cho container chứa các view khác. Ví dụ: LinearLayout là ViewGroup vì nó chứa được các view và layout khác.
Ngược lại, View là khối xây dựng cơ bản của UI. View có thể là một phần của ViewGroup. Ví dụ: TextView là View.

Hệ thống phân cấp ViewGroup và View
Measure → Layout → Draw → Lặp lại
Layout được lưu dưới dạng file XML. Làm sao chúng chuyển thành đối tượng trên màn hình? Mỗi file XML được khởi tạo (inflate) và hình thành cây phân cấp view. Nếu layout B lồng trong layout A, chúng có quan hệ cha-con (A là cha của B). Khi cây hình thành, 3 giai đoạn xảy ra theo thứ tự duyệt cây theo chiều sâu (Depth First Search): Measure, Layout, Draw.
Measure
Giai đoạn đầu, mỗi node cha xác định các ràng buộc kích thước của con. Nó truyền các giới hạn xuống cho con, nơi mỗi con đánh giá kích thước mong muốn, xem xét giới hạn nhận được và giới hạn của các con của nó.
Layout
Tại đây, mỗi node quyết định kích thước và vị trí cuối cùng của các con trên màn hình.
Draw
Bắt đầu từ node gốc, vẽ chính nó, sau đó yêu cầu con vẽ mình. Cách này làm cha vẽ trước, con vẽ đè lên trên.
Giữ quy trình này trong tâm trí, bạn nên giữ layout ứng dụng càng nông càng tốt để giảm thời gian duyệt cây view

"assorted-color photo frame lot" bởi Markus Spiske trên Unsplash
Phân tích các Layout
LinearLayout
Sắp xếp con theo hàng ngang hoặc dọc (thuộc tính android:orientation). Tính năng thú vị: layout_weight - chia không gian giữa các view con. Hữu ích khi muốn layout nhất quán trên nhiều thiết bị và hướng xoay.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="World!" /> </LinearLayout>LinearLayout đơn giản
Muốn TextView "Hello" chiếm 3/4 chiều rộng màn hình? Dùng layout_weight:
<LinearLayout ... android:weightSum="4"> <TextView ... android:layout_weight="3" android:text="Hello" /> <TextView ... android:layout_weight="1" android:text="World!" /> </LinearLayout>Sử dụng layout_weight
RelativeLayout
Đặt view con ở vị trí tương đối. Giữ cây phân cấp phẳng, không lồng ViewGroup. Tuy nhiên, RelativeLayout cần 2 lượt Measure, ảnh hưởng hiệu năng.
Tính năng hữu ích: thuộc tính centerInParent để căn giữa view con.

layout_centerInParent căn giữa TextView
ConstraintLayout
Constraint là kết nối hoặc căn chỉnh đến element được ràng buộc. Định nghĩa nhiều constraint cho mỗi view con liên quan đến các view khác. Xây dựng layout phức tạp với cây phân cấp phẳng (không lồng ViewGroup). Tương tự RelativeLayout, cũng cần 2 lượt Measure.

Các constraint trên TextView
FrameLayout
Chỉ chứa một view con đơn lẻ, chặn các view khác. Kích thước layout bằng view con lớn nhất (hiển thị hoặc không) cộng padding. Tránh đặt nhiều view con trong FrameLayout vì khó tránh chồng chéo. Kiểm soát vị trí bằng thuộc tính layout_gravity cho mỗi con.

ListView / GridView
Dùng khi cần hiển thị nhiều item (như menu nhà hàng). ListView: danh sách cột đơn, cuộn dọc. GridView: ListView với nhiều cột.
Điểm quan trọng: View được tạo động tại runtime. Để populate item, cần dùng AdapterView.

Chỉ định vị trí item bằng layout_column và layout_row
TableLayout
Tương tự GridView, sắp xếp con thành hàng và cột. Mỗi layout chứa nhiều TableRow, mỗi TableRow định nghĩa một hàng.

Hai element TableRow
Đừng ngại thử các layout khác nhau cho đến khi tìm thấy phù hợp nhất. Hãy chia sẻ trong comment layout nào hữu ích nhất cho bạn và lý do.