Chắc hẳn Constraint layout đã khá quen thuộc với các lập trình viên Android rồi , nên hôm nay mình xin chia sẻ cho mọi người một số thứ hay ho mà thằng Constraint layout làm được

Giới thiệu chung về Constraint layout

  • Constraint layout được giới thiệu lần đầu tiên tại sự kiện Google I/O 2016
  • Constraint Layout sẵn dùng với bản Android 2.3 (API level 9)
  • Bản mới nhất ConstraintLayout 1.1.0 beta 5

MATCH_CONSTRAINT

Giá trị match_parent khi xác định width và height của một View sẽ không còn được hỗ trợ với ConstraintLayout nữa.

Thay vào đó, ConstraintLayout giới thiệu một giá trị khác: match_constraint cũng có mục đích tương tự với match_parent

Sử dụng match_constraint bằng cách

  • set layout_width hoặc layout_height bằng 0dp
  • neo 2 cạnh đối diện của View vào 2 bên tương ứng để width/ height của View tràn ra và đạt được hiệu ứng như match_parent.

Margins khi một view bị GONE

Như bình thường khi muốn căn lề chúng ta sẽ sử dụng android:layout_margin
Vấn đề ở đây khi một view được GONE đi, mọi giá trị size của View đều sẽ bằng 0dp nhưng vẫn sẽ tham gia vào quá trình tính toán các ràng buộc.
Cùng với đó, tất cả các margin đối với những ràng buộc của View này cũng sẽ được set bằng 0dp.
Trong trường hợp đó các ràng buộc sẽ bị phá vỡ.

Bởi vậy, ConstraintLayout đã cung cấp thêm một số thuộc tính mới dành cho margin  layout_goneMargin để xác định margin trong trường hợp View được lấy làm mỏ để neo bị GONE

Lưu ý: giá trị margin này sẽ chỉ có tác dụng trong trường hợp View làm mỏ neo bị biến mất

    app:layout_goneMarginEnd="1dp"
    app:layout_goneMarginTop="1dp"
    app:layout_goneMarginLeft="1dp"
    app:layout_goneMarginRight="1dp"`

Bias trong Constraint layout

Để một View được căn vào giữa của 2 cạnh của một View khác , ta chỉ cần neo 2 cạnh (hoặc 4 cạnh) của View đó vào 2 cạnh (hoặc 4 cạnh) của view khác là được.

VD : TextView dưới được set nằm giữa view parent

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text View 1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Nhưng giờ ta muốn TextView trên căn theo tỉ lệ khác ( không phải 50:50 ) trong Constraint layout có thêm

layout_constraintHorizontal_bias

layout_constraintVertical_bias

Bias thể hiểu là bạn muốn sắp xếp View này thiên về bên nào hơn
Thuộc tính này chỉ có tác dụng khi View đang neo 2 cạnh đối diện hoặc cả 4 cạnh. 
ConstraintLayout cung cấp thuộc tính này cho cả chiều ngang (horizontal) và chiều dọc (vertical).

Vd : Khi thêm app:layout_constraintHorizontal_bias="0.2" sẽ ra được như này

Chains trong Constraint layout

Các Chain (chuỗi) cung cấp hành vi giống như nhóm theo một trục đơn (theo chiều ngang hoặc chiều dọc

Để tạo một chain, ta cần kết nối các View với nhau theo cả 2 hướng (bi-directional connection)

Hai hướng ở đây có nghĩa là đuôi của view 1 neo vào đầu của view 2 và đầu của view 2 cũng cần được neo vào đuôi của view 1. ( nếu không sẽ không tính là chain)

Lưu ý :

  • các thuộc tính của cả chain đó sẽ được thiết lập ở phần tử đầu tiên của chain (head chain): phần tử phía bên trái nhất đối với horizontal chain hoặc phần tử trên cùng với vertical chain

== > chỉ cần set chainStyle cho HeadChain

Dưới đây là một số chainStyle của Chain

CHAIN_SPREAD Các các phần tử trong chain sẽ được trải ra (kiểu mặc định)

CHAIN_SPREAD_INSIDE – tương tự, nhưng điểm đầu và cuối của chuỗi sẽ được dàn rộng ra sát hai bên

CHAIN_PACKED Các phần tử của chuỗi sẽ được đóng gói với nhau.

CHAIN_PACKED + Bias : sẽ căn chỉnh lại tỉ lệ của chain đó

Weighted chain

  • Khi style của chain được set là  CHAIN_SPREAD  hoặc CHAIN_SPREAD_INSIDE
  • dụng thuộc tính  layout_constraintHorizontal_weight hoặc  layout_constraintVertical_weight để chia phần

Tạo giới hạn giữa các view

<TextView
android:id="@+id/textView1"
android:layout_marginStart="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="textView2,textView1" />

Khi điều chỉnh kích cỡ của TextView thì barrier thay đổi kích thước của chúng theo view mà nó đã rằng buộc.

Có 2 thuộc tính cần lưu ý :

  • app:barrierDirection quyết định sự sự ràng buộc của Barrier- trong trường hợp trên nó sẽ được bố trí tại end các Views tham chiếu
  • constraint_referenced_ids : danh sách các view ID được tham chiếu ( phân tách bằng dấu phẩy)

Và kết quả như bên dưới :

Tổng kết

Trên đây là một số điểm thú vị của Constraint Layout mà mình biết

Hy vọng bài viết sẽ giúp ích được các bạn khi sử dụng Constraint Layout

Nguồn tham khảo :

https://developer.android.com/training/constraint-layout/index.html
https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html
https://constraintlayout.com/basics/barriers.html