Bắt đầu một hoạt động bằng ảnh động

Thử cách dùng Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng ảnh động trong Compose.

Hiệu ứng chuyển đổi hoạt động trong các ứng dụng Material Design tạo ra mối liên kết trực quan giữa các trạng thái thông qua chuyển động và biến đổi giữa các phần tử phổ biến. Bạn có thể chỉ định ảnh động tuỳ chỉnh cho hiệu ứng chuyển đổi vào và thoát cũng như hiệu ứng chuyển đổi của các phần tử được chia sẻ giữa các hoạt động.

Hình 1 Một hiệu ứng chuyển đổi với các phần tử được chia sẻ.

  • Hiệu ứng chuyển đổi enter (nhập) xác định cách các thành phần hiển thị trong một hoạt động xuất hiện trong cảnh. Ví dụ: trong hiệu ứng chuyển đổi nhập explode, các thành phần hiển thị sẽ đi vào cảnh từ bên ngoài và bay vào giữa màn hình.
  • Hiệu ứng chuyển đổi thoát xác định cách các thành phần hiển thị trong một hoạt động thoát khỏi cảnh. Ví dụ: trong hiệu ứng chuyển đổi thoát explode, các thành phần hiển thị sẽ thoát khỏi cảnh ra khỏi tâm.
  • Hiệu ứng chuyển đổi thành phần dùng chung xác định cách các thành phần hiển thị được chia sẻ giữa hai hoạt động chuyển đổi giữa các hoạt động này. Ví dụ: nếu hai hoạt động có cùng một hình ảnh ở các vị trí và kích thước khác nhau, thì hiệu ứng chuyển đổi phần tử dùng chung changeImageTransform sẽ dịch và điều chỉnh hình ảnh một cách mượt mà giữa các hoạt động này.

Android hỗ trợ các hiệu ứng chuyển đổi vào và ra sau:

  • explode: di chuyển thành phần hiển thị vào hoặc ra khỏi tâm của cảnh.
  • slide: di chuyển thành phần hiển thị vào hoặc ra khỏi một trong các cạnh của cảnh.
  • fade: thêm hoặc xoá một thành phần hiển thị khỏi cảnh bằng cách thay đổi độ mờ của thành phần đó.

Mọi hiệu ứng chuyển đổi mở rộng lớp Visibility đều được hỗ trợ dưới dạng hiệu ứng chuyển đổi vào hoặc ra. Để biết thêm thông tin, hãy xem tài liệu tham khảo API cho lớp Transition.

Android cũng hỗ trợ các hiệu ứng chuyển đổi phần tử dùng chung sau:

  • changeBounds: tạo ảnh động cho các thay đổi trong giới hạn bố cục của thành phần hiển thị mục tiêu.
  • changeClipBounds: tạo ảnh động cho các thay đổi trong giới hạn clip của thành phần hiển thị mục tiêu.
  • changeTransform: tạo ảnh động cho các thay đổi về tỷ lệ và độ xoay của thành phần hiển thị mục tiêu.
  • changeImageTransform: tạo ảnh động cho các thay đổi về kích thước và tỷ lệ của hình ảnh mục tiêu.

Khi bạn bật hiệu ứng chuyển đổi hoạt động trong ứng dụng, hiệu ứng chuyển đổi làm mờ mặc định sẽ kích hoạt giữa các hoạt động vào và ra.

Hình 2. Chuyển đổi cảnh với một phần tử dùng chung.

Để biết mã mẫu tạo ảnh động giữa các hoạt động bằng các thành phần được chia sẻ, hãy xem phần ActivitySceneTransitionBasic.

Kiểm tra phiên bản hệ thống

API chuyển đổi hoạt động có trên Android 5.0 (API 21) trở lên. Để duy trì khả năng tương thích với các phiên bản Android cũ, hãy kiểm tra version của hệ thống trong thời gian chạy trước khi gọi API cho bất kỳ tính năng nào sau đây:

Kotlin

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

Java

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

Chỉ định hiệu ứng chuyển đổi tuỳ chỉnh

Trước tiên, hãy bật hiệu ứng chuyển đổi nội dung cửa sổ bằng thuộc tính android:windowActivityTransitions khi bạn xác định một kiểu kế thừa từ giao diện Material. Bạn cũng có thể chỉ định hiệu ứng chuyển đổi phần tử được chia sẻ, nhập và thoát trong định nghĩa kiểu:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

Quá trình chuyển đổi change_image_transform trong ví dụ này được xác định như sau:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

Phần tử changeImageTransform tương ứng với lớp ChangeImageTransform. Để biết thêm thông tin, hãy xem tài liệu tham khảo về API cho Transition.

Để bật hiệu ứng chuyển đổi nội dung cửa sổ trong mã, hãy gọi hàm Window.requestFeature():

Kotlin

// Inside your activity (if you did not enable transitions in your theme)
with(window) {
    requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)

    // Set an exit transition
    exitTransition = Explode()
}

Java

// Inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);

// Set an exit transition
getWindow().setExitTransition(new Explode());

Để chỉ định các hiệu ứng chuyển đổi trong mã, hãy gọi các hàm này bằng đối tượng Transition:

Hàm setExitTransition()setSharedElementExitTransition() xác định quá trình chuyển đổi thoát cho hoạt động gọi. Hàm setEnterTransition()setSharedElementEnterTransition() xác định quá trình chuyển đổi vào cho hoạt động được gọi.

Để có được hiệu ứng đầy đủ của một hiệu ứng chuyển đổi, bạn phải bật hiệu ứng chuyển đổi nội dung cửa sổ trên cả hoạt động gọi và hoạt động được gọi. Nếu không, hoạt động gọi sẽ bắt đầu quá trình chuyển đổi thoát, nhưng sau đó bạn sẽ thấy các hiệu ứng chuyển đổi cửa sổ, chẳng hạn như thu nhỏ hoặc mờ.

Để bắt đầu chuyển đổi nhập sớm nhất có thể, hãy sử dụng hàm Window.setAllowEnterTransitionOverlap() trên hoạt động được gọi. Điều này cho phép bạn có các hiệu ứng chuyển đổi khi nhập ấn tượng hơn.

Bắt đầu một hoạt động bằng hiệu ứng chuyển đổi

Nếu bạn bật hiệu ứng chuyển đổi và đặt hiệu ứng chuyển đổi thoát cho một hoạt động, thì hiệu ứng chuyển đổi sẽ kích hoạt khi bạn khởi chạy một hoạt động khác, như sau:

Kotlin

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle())

Java

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

Nếu bạn đặt hiệu ứng chuyển đổi khi nhập cho hoạt động thứ hai, thì hiệu ứng chuyển đổi đó cũng sẽ kích hoạt khi hoạt động bắt đầu. Để tắt hiệu ứng chuyển đổi khi bạn bắt đầu một hoạt động khác, hãy cung cấp gói tuỳ chọn null.

Bắt đầu một hoạt động bằng phần tử được chia sẻ

Để tạo ảnh động chuyển đổi màn hình giữa hai hoạt động có một phần tử dùng chung, hãy làm như sau:

  1. Bật tính năng chuyển đổi nội dung cửa sổ trong giao diện.
  2. Chỉ định hiệu ứng chuyển đổi phần tử dùng chung trong kiểu của bạn.
  3. Xác định hiệu ứng chuyển đổi dưới dạng tài nguyên XML.
  4. Chỉ định tên chung cho các phần tử dùng chung trong cả hai bố cục bằng thuộc tính android:transitionName.
  5. Sử dụng hàm ActivityOptions.makeSceneTransitionAnimation().

Kotlin

// Get the element that receives the click event
val imgContainerView = findViewById<View>(R.id.img_container)

// Get the common element for the transition in this activity
val androidRobotView = findViewById<View>(R.id.image_small)

// Define a click listener
imgContainerView.setOnClickListener( {
    val intent = Intent(this, Activity2::class.java)
    // Create the transition animation - the images in the layouts
    // of both activities are defined with android:transitionName="robot"
    val options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot")
    // Start the new activity
    startActivity(intent, options.toBundle())
})

Java

// Get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// Get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// Define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // Create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // Start the new activity
        startActivity(intent, options.toBundle());
    }
});

Đối với các thành phần hiển thị động dùng chung mà bạn tạo trong mã, hãy sử dụng hàm View.setTransitionName() để chỉ định tên thành phần chung trong cả hai hoạt động.

Để đảo ngược ảnh động chuyển đổi cảnh khi bạn hoàn tất hoạt động thứ hai, hãy gọi hàm Activity.finishAfterTransition() thay vì Activity.finish().

Bắt đầu một hoạt động có nhiều phần tử dùng chung

Để tạo ảnh động chuyển đổi cảnh giữa hai hoạt động có nhiều phần tử dùng chung, hãy xác định các phần tử dùng chung trong cả hai bố cục bằng thuộc tính android:transitionName hoặc sử dụng hàm View.setTransitionName() trong cả hai hoạt động và tạo đối tượng ActivityOptions như sau:

Kotlin

// Rename the Pair class from the Android framework to avoid a name clash
import android.util.Pair as UtilPair
...
val options = ActivityOptions.makeSceneTransitionAnimation(this,
        UtilPair.create(view1, "agreedName1"),
        UtilPair.create(view2, "agreedName2"))

Java

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"));