Liên hệ
android java

Sử dụng ConstraintLayout trong Android

Dùng ConstraintLayout để xây dựng các layout trong lập trình Android, với tính năng ràng buộc các phần tử, thiết lập các xích đa dạng

ConstraintLayout trong Android

ConstraintLayout là một layout mạnh, khuyến khích bạn dùng nếu có thể vì nó giúp tạo ra các giao diện phức tạp, mềm dẻo (hạn chế tối đa sử dụng các layout lồng nhau). Nó giúp định vị, sắp xếp các View con dựa trên sự ràng buộc liên hệ của các View con với View cha và sự liên hệ ràng buộc giữa các View con với nhau, với cơ chế tạo xích các View, gán trọng số hay sử dụng trợ giúp giao diện với Guideline.

ConstraintLayout thuộc Libaray Support nên để tích hợp vào dự án hãy thêm vào Gradle phiên bản muốn dùng, ví dụ:

implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'

Sự ràng buộc

Mỗi view trong ConstraintLayout để định vị được chính xác cần tối thiếu 2 ràng buộc, một theo phương ngang (X) và một theo phương đứng (Y)

Khái niệm ràng buộc giữa các phần tử ở đây ám chỉ sự liên kết với nhau của các phần tử với nhau (kể cả với phần tử cha ConstraintLayout), sự căn chỉnh phần tử theo phần tử khác, hoặc với những đường thẳng ẩn thêm vào. Mỗi ràng buộc của phần tử View sẽ hoặc hưởng đến vị trí của nó theo trục X hoặc trục Y. Các View không có ràng buộc sẽ định vị ở góc trái - trên (tọa độ 0,0).

Trước tiên tham khảo bảng các thuộc tính về ràng buộc layout_constraint ... , các thuộc tính ràng buộc sử dụng với namespace:app, giá trị nó gán vào là một ID của phần tử khác để kết nối ràng buộc hoặc là phần tử ch bằng hằng số "parent", ví dụ:

app:layout_constraintBottom_toBottomOf="parent"
Ràng buộcÝ nghĩa ràng buộc
layout_constraintLeft_toLeftOf Rang buộc cạnh trái của phần tử tới phần tử chỉ ra trong giá trị (gán ID)
layout_constraintLeft_toRightOf Bên trái với bên phải của phần tử chỉ ra
layout_constraintRight_toLeftOf Bên phải với bên trái
layout_constraintRight_toRightOf Phải với phải
layout_constraintTop_toTopOf Cạnh trên với cạnh trên
layout_constraintTop_toBottomOf Cạnh trên nối với cạnh dưới
layout_constraintBottom_toTopOf Dưới với trên
layout_constraintBottom_toBottomOf Dưới với dưới
layout_constraintBaseline_toBaselineOf Trùng Baseline
layout_constraintStart_toEndOf Bắt đầu - Kết húc
layout_constraintStart_toStartOf Bắt đầu - Bắt đầu
layout_constraintEnd_toStartOf Cuối với bắt đầu
layout_constraintEnd_toEndOf Cuối với cuối

Thuộc tính Margin trong các phần tử con

Cạnh nào của View con có ràng buộc thì có thể thiết lập thêm thuộc tính Margin để điều chỉnh thêm khoảng cách các cạnh tới điểm nối ràng buộc.

Các thuộc tính margin theo các cạnh: android:layout_marginStart, android:layout_marginEnd, android:layout_marginLeft, android:layout_marginTop, android:layout_marginRight, android:layout_marginBottom

Tương tự có layout_goneMarginStart, layout_goneMarginEnd, layout_goneMarginLeft, layout_goneMarginTop, layout_goneMarginRight, layout_goneMarginBottom có hiệu lực khi đối tượng ràng buộc đến gone

Phần tử Guideline

Ta có thể một đường kẻ ẩn trong ConstraintLayout nằm ngang hoặc đứng nó như là một View con để các View khác ràng buộc đến nếu muốn. Thêm vào bằng cách:

<android.support.constraint.Guideline
    android:id="@+id/guideline_1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.3" />

Thiết lập đó là được kẻ ngang bằng thuộc tính: android:orientation="horizontal" đường kể đứng android:orientation="vertical"

Vị trí phân chia ContraintLayout của GuideLine

1 Vị trị của Guideline có thể thiết lập nó cách cạnh trái (hoặc trên nếu là Guideline ngang) bằng thuộc tính app:layout_constraintGuide_percent giá trị là tỷ lệ phần trăm như 0.5 (50%), 0.2 (20%) độ rộng (cao) của ConstraintLayout. Ví dụ: app:layout_constraintGuide_percent="0.1"

Ví dụ:

<?xml version="1.0" encoding="utf-8"?>
<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">


    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:text="Button1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="20dp"
        android:text="BUTTON2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/button" />

</android.support.constraint.ConstraintLayout>

2 Nếu không muốn sử dụng layout_constraintGuide_percent thì có thể sử dụng cách thiết lập Guideline cách cạnh bắt đầu (trên với Guidleline ngang) bao nhiêu bằng thuộc tính: app:layout_constraintGuide_begin ví dụ:

app:layout_constraintGuide_begin="100dp"

Hoặc thiết lập cách cạnh cuối bao nhiêu với layout_constraintGuide_end

Bias

Khi hai cạnh đối diện nhau của View có ràng buộc, thì hai dàng buộc này ứng xử như một liên kết lò xo mặc định nó có độ mềm (độ cứng) bằng nhau dẫn đến View sẽ nằm giữa 2 điểm neo của ràng buộc. Nếu muốn điều chỉnh độ cứng này thì sử dụng thuộc tính:

  • app:layout_constraintVertical_bias thiết lập độ mềm của ràng buộc đầu (ngang). Với tổng độ mềm là 1 thì khi app:layout_constraintVertical_bias="0.1" thì độ mềm ràng buộc thứ hai sẽ là 0.9
  • layout_constraintHorizontal_bias để thiết lập độ mềm hai ràng buộc theo phương đứng

Tỷ lệ các cạnh của View

Khi View con có thiết lập tối thiểu một kích thước là "0dp" thì kích thước đó có thể tự động điều chỉnh bằng cách lấy theo tỷ lệ với cạnh còn lại, thuộc tính app:layout_constraintDimensionRatio cho phép gán tỷ lệ giữa chiều rộng và chiều cao, ví dụ: app:layout_constraintDimensionRatio="2:1" chiều rộng gấp đôi chiều cao

Chain - xích các View lại

Các View ràng buộc qua lại các cạnh tiếp giáp nhau sẽ tạo thành một xích các View. Có hai loại xích các phần tử theo phương ngang và theo phương đứng. Lúc đó, phần tử đầu tiên có chức năng thiết lập chung một số thông số về xích.

Một xích theo phương ngang

Phần tử đầu của xích thiết lập kiểu xích bằng thuộc tính: app:layout_constraintHorizontal_chainStyleapp:layout_constraintVertical_chainStyle tùy theo xích đứng hay ngang, mặc định xích có kiểu spread

xích "spread": app:layout_constraintHorizontal_chainStyle="spread" hoặc app:layout_constraintVertical_chainStyle="spread"

Ví dụ: (2 xích ngang và đứng)

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:layout_editor_absoluteY="81dp">


    <Button
        android:id="@+id/b1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#1eb729"
        android:text="B1 - HEAD"
        app:layout_constraintBottom_toTopOf="@id/b5"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintRight_toLeftOf="@id/b2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/b4" />

    <Button
        android:id="@+id/b2"
        android:text="B2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/b1"
        app:layout_constraintRight_toLeftOf="@id/b3"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/b3"
        android:text="B3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toRightOf="@id/b2"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/b4"
        android:text="B4 - HEAD"
        android:textColor="#cf3131"
        app:layout_constraintBottom_toTopOf="@id/b1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/b1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/b5"
        android:text="B5"
        app:layout_constraintTop_toBottomOf="@id/b1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/b1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</android.support.constraint.ConstraintLayout>

xích "packed": app:layout_constraintHorizontal_chainStyle="packed" hoặc app:layout_constraintVertical_chainStyle="packed"

xích "spread_inside": app:layout_constraintHorizontal_chainStyle="spread_inside" hoặc app:layout_constraintVertical_chainStyle="spread_inside"

Với loại spread_insidespread theo phương của xích các phần tử có thể gán kích thước bằng 0 và điều chỉnh lại theo trọng số weight với ý nghĩa tương tự như LinearLayout, thuộc tính thiết lập trọng số là: app:layout_constraintHorizontal_weight và app:layout_constraintVertical_weight

Ví dụ:

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:layout_editor_absoluteY="81dp">


    <Button
        android:id="@+id/b1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:textColor="#1eb729"
        android:text="B1 - HEAD"
        app:layout_constraintBottom_toTopOf="@id/b5"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintRight_toLeftOf="@id/b2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintVertical_weight="2"
        app:layout_constraintTop_toBottomOf="@id/b4" />

    <Button
        android:id="@+id/b2"
        android:text="B2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/b1"
        app:layout_constraintRight_toLeftOf="@id/b3"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/b3"
        android:text="B3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="3"
        app:layout_constraintLeft_toRightOf="@id/b2"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/b4"
        android:text="B4 - HEAD"
        app:layout_constraintVertical_chainStyle="spread_inside"
        android:textColor="#cf3131"
        app:layout_constraintBottom_toTopOf="@id/b1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/b1"
        app:layout_constraintVertical_weight="1"
        android:layout_width="wrap_content"
        android:layout_height="0dp" />

    <Button
        android:id="@+id/b5"
        android:text="B5"
        app:layout_constraintTop_toBottomOf="@id/b1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/b1"
        android:layout_width="wrap_content"
        app:layout_constraintVertical_weight="3"
        android:layout_height="0px" />

</android.support.constraint.ConstraintLayout>

Vui lòng đăng ký ủng hộ kênh