Giới thiệu
Là layout mặc định kể từ Android Studio 3.0, ConstraintLayout giúp cho việc thiết kế các layouts phức tạp trở nên đơn giản hơn bằng cách cho phép các views kết nối với nhau thông qua các ràng buộc (constraints) dựa trên mối quan hệ giữa các views khác nhau, và quan trọng hơn, ConstraintLayout hướng tới việc thiết kế giảm các views lồng nhau – điều này sẽ làm tăng hiệu suất thực thi cho các tập tin layout.
Dùng ConstraintLayout với mã XML
Định vị các views
ConstraintLayout cung cấp các thuộc tính cho phép chúng ta định vị view hiện tại một cách dễ dàng. Các thuộc tính được mô tả như bảng sau:
Các thuộc tính | Mô tả |
layout_constraintTop_toTopOf | Ràng buộc phần trên (top) của view hiện tại đến phần trên của view khác. |
layout_constraintTop_toBottomOf | Ràng buộc phần trên của view hiện tại đến phần dưới (bottom) của view khác. |
layout_constraintBottom_toTopOf | Ràng buộc phần dưới của view hiện tại đến phần trên của view khác. |
layout_constraintBottom_toBottomOf | Ràng buộc phần dưới của view hiện tại đến phần dưới của view khác. |
layout_constraintLeft_toTopOf | Ràng buộc bên trái (left) của view hiện tại đến phần trên của view khác. |
layout_constraintLeft_toBottomOf | Ràng buộc bên trái của view hiện tại đến phần dưới của view khác. |
layout_constraintLeft_toLeftOf | Ràng buộc bên trái của view hiện tại đến bên trái của view khác. |
layout_constraintLeft_toRightOf | Ràng buộc bên trái của view hiện tại đến bên phải (right) của view khác. |
layout_constraintRight_toTopOf | Ràng buộc bên phải của view hiện tại đến phần trên của view khác. |
layout_constraintRight_toBottomOf | Ràng buộc bên phải của view hiện tại đến phần dưới của view khác. |
layout_constraintRight_toLeftOf | Ràng buộc bên phải của view hiện tại đến bên trái của view khác. |
layout_constraintRight_toRightOf | Ràng buộc bên phải của view hiện tại đến bên phải của view khác. |
Start, End | Chúng ta có thể dùng Start để thay thế cho Left và dùng End để thay thế cho Right. Lưu ý rằng, khi dùng Start thì phải dùng Start hay End tương ứng, không được dùng Start kết hợp với Left hay Right.
Ví dụ layout_constraintRight_toLeftOf tương đương với layout_constraintEnd_toStartOf |
layout_constraintHorizontal_bias | Định vị view theo trục ngang màn hình. |
layout_constraintVertical_bias | Định vị view theo trục dọc màn hình. |
Kích cỡ các views
Giống như các views, ConstraintLayout cung cấp hai thuộc tính là layout_width và layout_height cho phép chúng ta điểu khiển kích cỡ của ConstraintLayout như ý. Có 3 kiểu giá trị phổ biến dùng cho layout_width và layout_height như sau:
- Tùy ý, ví 18dp hay 133dp: kích cỡ layout là cố định theo giá trị cho trước
- wrap_content: điều chỉnh kích cỡ layout vừa khớp với nội dung bên trong nó
- match_parent: mở rộng kích cỡ layout khớp kích cỡ của view cha hay view chứa nó
Đoạn mã XML sau định vị một TextView trong một ConstraintLayout:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
Giá trị của layout_width và layout_height của ConstraintLayout là match_parent có nghĩa là kích cỡ của ConstraintLayout được mở rộng khớp với toàn bộ màn hình hiển thị (vì ConstraintLayout trong trường hợp này là view gốc nên không có view cha); giá trị hai thuộc tính này của TextView là wrap_content nghĩa là kích cỡ TextView được điều chỉnh vừa khớp với nội dung bên trong nó.
Phần trên, dưới, trái, phải của TexView được kết nối đến phần trên, dưới, trái, phải của view cha hay ConstraintLayout một cách tương ứng:
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"
Ở đây, giá trị của các thuộc tính là parent thể hiện sự ràng buộc đến view cha (parent view). Trong trường hợp ràng buộc đến một view khác thì cần chỉ ra id của view đó như đoạn mã sau:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" app:layout_constraintVertical_bias="0.006" /> </android.support.constraint.ConstraintLayout>
Chúng ta có thể thấy rằng, ConstraintLayout chứa hai view con là TextView và Button. Trái, phải và dưới của Button ràng buộc đến trái, phải và dưới của ConstraintLayout tương ứng (giá trị là parent), trong khi đó phần trên của Button thì ràng buộc đến phần dưới của TextView:
app:layout_constraintTop_toBottomOf="@+id/textView"
Một cách trực quan:
Cũng cần lưu ý rằng, vì Button ràng buộc đến TextView theo chiều dọc nên thuộc tính layout_constraintVertical_bias được sử dụng:
app:layout_constraintVertical_bias="0.006"
Dùng ConstraintLayout với công cụ trực quan
Cách nhanh nhất và hiệu quả nhất là thiết kế giao diện dùng công cụ trực quan. Các views được cung sẵn từ thanh công cụ Palette và chúng ta đã làm quen từ bài trước. Mặc định, Android Studio 3.0 (hay cao hơn) dùng ConstraintLayout như là view gốc của giao diện. Chúng ta có thể kéo ConstraintLayout từ thanh Palette và thả vào giao diện
Một view khi kéo từ thanh Palette và thả vào trong ConstraintLayout sẽ như sau:
Bốn chấm tròn màu trắng xung quanh TextView có nghĩa rằng TextView chưa được kết nối hay ràng buộc đến view cha (hay các view khác). Để thực hiện kết nối chúng ta chỉ việc chọn một trong các dấu chấm tròn và rê con trỏ chuột về hướng cần ràng buộc. Ví dụ ràng buộc phần trên của TextView đến phần trên của ConstraintLayout bằng cách chọn dấu chấm tròn trắng ở phần trên của TextView và rê con trỏ chuột về hướng phần trên của ConstraintLayout:
TextView sau khi ràng buộc các phần trái, phải, trên, dưới đến ConstraintLayout sẽ như sau:
Lúc này, các dấu chấm tròn chuyển sang màu xanh. Mỗi một view sẽ có một khung nhìn tương ứng. Khoảng cách từ khung nhìn của view con, trong trường hợp này là TextView, đến viền của view cha (ConstraintLayout) gọi là margin. Nhìn lên hình trên chúng ta thấy các số 128, 8, 8 là các margin đến lề trái, lề phải và lề trên của ConstraintLayout. Khoảng cách mặc định các margin là 8dp và chúng ta có thể thay đổi giá trị này trên thanh công cụ:
Với TextView và ConstraintLayout, chúng ta có thể xem margin từ cửa sổ Attributes của TextView:
Giới hạn khung nhìn của TextView cũng có thể được xác định qua các đường kết nối giữa TextView và ConstraintLayout:
Mở rộng kích cỡ TextView bằng cách đưa con trỏ chuột đến các góc của TextView cho đến khi xuất hiện dấu mũi tên hai đầu màu trắng và mở rộng kích cỡ về hướng tương ứng
Chúng ta cũng có thể mở rộng từ các cạnh trái, phải, trên, dưới:
Khi mở rộng kích cỡ đến biên của khung nhìn TextView, các phần xoắn (dạng lò xo) của đường kết nối sẽ không còn:
Nếu tiếp tục mở rộng vượt qua ranh giới margin sẽ lại xuất hiện phần xoắn:
Giá trị các margin có thể thay đổi từ khung Attributes:
Thuộc tính XML tương ứng cho các margin là: layout_marginLeft, layout_marginRight, layout_marginTop, layout_marginBottom, layout_marginStart, layout_marginEnd.
Xóa ràng buộc theo hai cách:
- Xóa từng ràng buộc bằng cách nhấp chuột trái vào dấu chấm tròn tương ứng
- Xóa tất cả ràng buộc bằng cách chọn biểu tượng Clear All Contraints (trên thanh công cụ hay tại view)
Chúng ta cũng có thể cho phép các views tự động thiết lập các ràng buộc đến view cha hay các views khác một cách tự động bằng cách bật tính năng Autoconnect:
Đóng Autoconnect:
Dùng ConstraintLayout với Java
Tạo một thể hiện ConstraintLayout:
ConstraintLayout myLayout = new ConstraintLayout(this);
Thêm một view đến ConstraintLayout dùng phương thức addView:
Button myButton = new Button(this); myLayout.addView(myButton);
Hiển thị ConstraintLayout đến người dùng bằng phương thức setContentView:
setContentView(myLayout);
Có thể sử dụng ConstraintLayout với đối tượng ConstraintSet như trong bài Thiết kế giao diện người dùng với mã Java.
Tổng kết
Trong bài này chúng ta đã tìm hiểu một cách khái quát về cách dùng đối tượng ConstraintLayout theo ba cách: XML, công cụ trực quan, và mã Java. Chúng ta có thể học nhiều hơn về ConstraintLayout bằng cách tham khảo:
Ý kiến bài viết