MotionLayout
là loại bố cục giúp bạn quản lý ảnh động chuyển động và tiện ích trong ứng dụng.
MotionLayout
là lớp con của
ConstraintLayout
và được xây dựng dựa trên
khả năng bố cục. Nằm trong thư viện ConstraintLayout
, MotionLayout
có sẵn dưới dạng thư viện hỗ trợ.
MotionLayout
thu hẹp khoảng cách giữa chuyển đổi bố cục và chuyển động phức tạp
cung cấp một kết hợp các tính năng giữa ảnh động thuộc tính
khung,
TransitionManager
và
CoordinatorLayout
.
Ngoài việc mô tả quá trình chuyển đổi giữa các bố cục, MotionLayout
còn cho phép bạn
tạo ảnh động cho mọi thuộc tính bố cục. Hơn nữa, nền tảng này vốn hỗ trợ những người có thể tìm kiếm
hiệu ứng chuyển cảnh. Điều này có nghĩa là bạn có thể hiển thị ngay bất kỳ điểm nào trong hiệu ứng chuyển đổi
dựa trên một số điều kiện, chẳng hạn như nhập bằng cách chạm. MotionLayout
cũng hỗ trợ
khung hình chính, bật các hiệu ứng chuyển cảnh được tuỳ chỉnh hoàn toàn cho phù hợp với nhu cầu của bạn.
MotionLayout
mang tính khai báo đầy đủ, nghĩa là bạn có thể mô tả mọi hiệu ứng chuyển đổi trong
XML, bất kể phức tạp đến mức nào.
Cân nhắc về thiết kế
MotionLayout
dùng để di chuyển, đổi kích thước và tạo ảnh động cho các phần tử trên giao diện người dùng mà
mà người dùng tương tác, chẳng hạn như nút và thanh tiêu đề. Không dùng chuyển động trong ứng dụng làm
một hiệu ứng đặc biệt vô cớ. Hãy sử dụng thông tin đó để giúp người dùng hiểu được ứng dụng của bạn là gì
đang làm. Để biết thêm thông tin về cách thiết kế ứng dụng bằng chuyển động, hãy xem
Mục Tìm hiểu về Material Design
chuyển động.
Bắt đầu
Hãy làm theo các bước sau để bắt đầu sử dụng MotionLayout
trong dự án của bạn.
-
Thêm phần phụ thuộc
ConstraintLayout
: để sử dụngMotionLayout
trong dự án của bạn, hãy thêm Phần phụ thuộcConstraintLayout
2.0 vào ứng dụng của bạnbuild.gradle
. Nếu bạn đang sử dụng AndroidX, hãy thêm phần phụ thuộc sau:Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha14" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha14" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha14") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha14") }
-
Tạo tệp
MotionLayout
:MotionLayout
là lớp con củaConstraintLayout
, nên bạn có thể biến đổi bất kỳConstraintLayout
hiện tại vàoMotionLayout
bằng cách thay thế tên lớp trong tệp tài nguyên bố cục, như minh hoạ trong các ví dụ sau:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Thư viện hỗ trợ
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Dưới đây là một ví dụ đầy đủ về tệp
MotionLayout
xác định bố cục như trong hình 1:AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout 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:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
Thư viện hỗ trợ
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout 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:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
Tạo MotionScene: trong
MotionLayout
trước Ví dụ: thuộc tínhapp:layoutDescription
tham chiếu đến cảnh chuyển động. Cảnh chuyển động là một tệp tài nguyên XML. Bên trong<MotionScene>
phần tử gốc, cảnh chuyển động chứa tất cả các mô tả chuyển động cho bố cục tương ứng. Để tách biệt thông tin bố cục với chuyển động phần mô tả, mỗiMotionLayout
tham chiếu đến một chuyển động riêng cảnh. Các định nghĩa trong cảnh chuyển động được ưu tiên hơn mọi định nghĩa tương tự định nghĩa trongMotionLayout
.Dưới đây là tệp cảnh chuyển động mẫu mô tả chiều ngang cơ bản chuyển động trong hình 1:
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
Xin lưu ý những điều sau:
-
<Transition>
chứa định nghĩa cơ sở của chuyển động.-
motion:constraintSetStart
vàmotion:constraintSetEnd
là các tham chiếu đến các điểm cuối của chuyển động. Các điểm cuối này được xác định trong Các phần tử<ConstraintSet>
ở phần sau trong cảnh chuyển động. -
motion:duration
chỉ định số mili giây cần thiết để hoàn tất chuyển động.
-
-
<OnSwipe>
cho phép bạn tạo điều khiển cảm ứng cho chuyển động.-
motion:touchAnchorId
đề cập đến chế độ xem mà người dùng có thể vuốt và kéo. -
motion:touchAnchorSide
có nghĩa là chế độ xem đang được kéo từ phía bên phải. -
motion:dragDirection
đề cập đến tiến trình hướng kéo. Ví dụ:motion:dragDirection="dragRight"
nghĩa là tiến trình sẽ tăng lên khi chế độ xem được kéo sang phải.
-
-
<ConstraintSet>
là nơi bạn xác định nhiều hạn chế mô tả chuyển động. Trong ví dụ này, một<ConstraintSet>
được xác định cho từng điểm cuối của chuyển động. Các điểm cuối này được căn giữa theo chiều dọc sử dụngapp:layout_constraintTop_toTopOf="parent"
vàapp:layout_constraintBottom_toBottomOf="parent"
Theo chiều ngang, các điểm cuối nằm ở phía ngoài cùng bên trái và bên phải của màn hình.
Để có cái nhìn chi tiết hơn về các yếu tố khác nhau trong một cảnh chuyển động hỗ trợ, hãy xem Ví dụ về MotionLayout.
-
Thuộc tính nội suy
Trong một tệp cảnh chuyển động, các phần tử ConstraintSet
có thể chứa thông tin bổ sung
được nội suy trong quá trình chuyển đổi. Ngoài vị trí và
thì các thuộc tính sau sẽ được nội suy bởi MotionLayout
:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,scaleY
Thuộc tính tùy chỉnh
Trong <Constraint>
, bạn có thể dùng phần tử <CustomAttribute>
để chỉ định
chuyển đổi cho các thuộc tính không chỉ liên quan đến vị trí hoặc View
.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
<CustomAttribute>
chứa hai thuộc tính riêng:
motion:attributeName
là bắt buộc và phải khớp với một đối tượng có phương thức getter và phương thức setter. Phương thức getter và setter phải khớp với một mẫu cụ thể. Cho Ví dụ:backgroundColor
được hỗ trợ, vì thành phần hiển thị có cơ sở Phương thứcgetBackgroundColor()
vàsetBackgroundColor()
.- Thuộc tính còn lại mà bạn phải cung cấp dựa trên loại giá trị. Chọn từ
các loại được hỗ trợ sau:
motion:customColorValue
cho màumotion:customIntegerValue
cho số nguyênmotion:customFloatValue
cho số thựcmotion:customStringValue
cho chuỗimotion:customDimension
cho phương diệnmotion:customBoolean
cho boolean
Khi chỉ định thuộc tính tuỳ chỉnh, hãy xác định giá trị điểm cuối ở cả điểm bắt đầu và
kết thúc phần tử <ConstraintSet>
.
Thay đổi màu nền
Dựa trên ví dụ trước, giả sử bạn muốn thay đổi màu của chế độ xem như một phần của chuyển động, như minh hoạ trong hình 2.
Thêm một phần tử <CustomAttribute>
vào mỗi phần tử ConstraintSet
, như minh hoạ trong
đoạn mã sau:
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet>
Các thuộc tính MotionLayout bổ sung
Ngoài các thuộc tính trong ví dụ trước, MotionLayout
có các thuộc tính khác
mà bạn có thể muốn chỉ định:
app:applyMotionScene="boolean"
cho biết có áp dụng cảnh chuyển động hay không. Giá trị mặc định của thuộc tính này làtrue
.app:showPaths="boolean"
cho biết liệu có hiển thị các đường chuyển động dưới dạng chuyển động đang chạy. Giá trị mặc định của thuộc tính này làfalse
.app:progress="float"
cho phép bạn chỉ định rõ tiến trình chuyển đổi. Bạn có thể sử dụng bất kỳ giá trị dấu phẩy động nào từ0
(bắt đầu chuyển đổi) đến1
(kết thúc quá trình chuyển đổi).app:currentState="reference"
cho phép bạn chỉ định mộtConstraintSet
cụ thể.app:motionDebug
cho phép bạn hiển thị thêm thông tin gỡ lỗi về chuyển động. Các giá trị có thể là"SHOW_PROGRESS"
,"SHOW_PATH"
hoặc"SHOW_ALL"
.
Tài nguyên khác
Để biết thêm thông tin về MotionLayout
, hãy xem các tài nguyên sau:
- Android nâng cao trong Kotlin 03.2: Ảnh động bằng MotionLayout
- Ví dụ về MotionLayout
- Mẫu MotionLayout/ConstraintLayout trên GitHub
- Giới thiệu về MotionLayout (phần I)
- Giới thiệu về MotionLayout (phần II)
- Giới thiệu về MotionLayout (phần III)
- Giới thiệu về MotionLayout (phần IV)