Thêm khả năng hỗ trợ cho tính năng xem trước thao tác quay lại

Hình 1. Bản minh hoạ giao diện tính năng xem trước thao tác quay lại trên điện thoại

Tính năng Xem trước thao tác quay lại (một tính năng điều hướng bằng cử chỉ) cho phép người dùng xem trước vị trí mà thao tác vuốt quay lại sẽ đưa họ đến.

Ví dụ: việc sử dụng cử chỉ quay lại có thể hiển thị bản xem trước dạng động của Màn hình chính đằng sau ứng dụng của bạn, như trình bày trong bản minh hoạ ở hình 1.

Kể từ Android 15, tuỳ chọn dành cho nhà phát triển về ảnh động xem trước thao tác quay lại sẽ không còn hoạt động nữa. Giờ đây, ảnh động hệ thống như thao tác quay lại màn hình chính, giữa các tác vụ và hoạt động sẽ xuất hiện cho những ứng dụng đã chọn sử dụng tính năng xem trước thao tác quay lại hoàn toàn hoặc ở cấp hoạt động.

Bạn có thể kiểm thử ảnh động quay lại màn hình chính này (như mô tả trong phần sau của trang này).

Nhằm hỗ trợ tính năng xem trước thao tác quay lại, bạn phải cập nhật ứng dụng bằng API OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) trở lên hoặc API nền tảng OnBackInvokedCallback mới có khả năng tương thích ngược. Hầu hết ứng dụng đều sử dụng API AndroidX có khả năng tương thích ngược.

Bản cập nhật này cung cấp một đường dẫn di chuyển để chặn thao tác quay lại sao cho đúng cách, thông qua việc thay thế tính năng chặn ngược từ KeyEvent.KEYCODE_BACK và bất kỳ lớp (class) nào bằng các phương thức onBackPressed như ActivityDialog nhờ Back API (API Quay lại) mới của hệ thống.

Lớp học lập trình và video về Google I/O

Ngoài việc sử dụng tài liệu này trên trang này, hãy thử tham khảo lớp học lập trình của chúng tôi. Lớp học này cung cấp cách triển khai trường hợp sử dụng phổ biến của WebView giúp xử lý tính năng xem trước thao tác quay lại bằng AndroidX Activity API.

Bạn cũng có thể xem video về Google I/O của chúng tôi, trong đó nêu thêm các ví dụ về việc triển khai AndroidX và API nền tảng.

Cập nhật một ứng dụng sử dụng tính năng điều hướng quay lại mặc định

Việc cập nhật ứng dụng để hỗ trợ tính năng này rất đơn giản nếu ứng dụng của bạn không triển khai hành vi quay lại tuỳ chỉnh nào (nói cách khác, ứng dụng sẽ để hệ thống phụ trách quá trình xử lý thao tác quay lại). Chọn sử dụng tính năng này bằng cách làm theo mô tả trong hướng dẫn này.

Nếu ứng dụng của bạn dùng Mảnh (Fragment) hoặc Thành phần điều hướng (Navigation component), hãy nâng cấp lên tối thiểu là AndroidX Activity 1.6.0-alpha05.

Cập nhật một ứng dụng dùng tính năng điều hướng quay lại tuỳ chỉnh

Nếu ứng dụng của bạn triển khai hành vi quay lại tuỳ chỉnh, thì sẽ có nhiều đường dẫn di chuyển tuỳ thuộc vào việc ứng dụng đó có sử dụng AndroidX hay không và cách xử lý thao tác điều hướng quay lại.

Ứng dụng của bạn sử dụng AndroidX Cách ứng dụng của bạn xử lý tính năng điều hướng quay lại Đường dẫn di chuyển đề xuất (đường liên kết trên trang này)
API AndroidX Di chuyển phương thức triển khai quay lại AndroidX hiện có
API nền tảng không được hỗ trợ Di chuyển ứng dụng AndroidX chứa API điều hướng quay lại không được hỗ trợ sang API AndroidX
Không API nền tảng không được hỗ trợ, có thể di chuyển Di chuyển ứng dụng dùng API điều hướng quay lại không được hỗ trợ sang API nền tảng
Các API nền tảng không được hỗ trợ nhưng không thể di chuyển Trì hoãn việc chọn tham gia cho đến khi đây là tính năng bắt buộc

Di chuyển cách triển khai tính năng điều hướng quay lại của AndroidX

Đây là trường hợp sử dụng phổ biến nhất (và được đề xuất nhiều nhất). Cách này áp dụng cho các ứng dụng mới hoặc ứng dụng hiện có triển khai cách xử lý thao tác bằng cử chỉ tuỳ chỉnh bằng OnBackPressedDispatcher, như mô tả trong phần Cung cấp tính năng điều hướng quay lại tuỳ chỉnh.

Nếu ứng dụng của bạn thuộc danh mục này, hãy làm theo các bước sau để thêm tính năng hỗ trợ cho cử chỉ vuốt ngược để dự đoán:

  1. Để đảm bảo rằng các API vốn đang sử dụng OnBackPressedDispatcher API (chẳng hạn như Mảnh và Thành phần điều hướng) hoạt động liền mạch với tính năng xem trước thao tác quay lại, hãy nâng cấp lên AndroidX Activity 1.6.0-alpha05.

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  2. Chọn sử dụng tính năng xem trước thao tác quay lại, theo mô tả trên trang này.

Di chuyển ứng dụng AndroidX chứa API điều hướng quay lại không được hỗ trợ sang API AndroidX

Nếu ứng dụng của bạn dùng thư viện AndroidX nhưng triển khai hoặc tham chiếu đến các API điều hướng quay lại không được hỗ trợ, thì bạn cần chuyển sang sử dụng API AndroidX để hỗ trợ hành vi mới.

Cách di chuyển API không được hỗ trợ sang API AndroidX:

  1. Di chuyển logic xử lý Quay lại của hệ thống sang OnBackPressedDispatcher của AndroidX bằng cách triển khai OnBackPressedCallback. Để biết hướng dẫn chi tiết, hãy xem bài viết Cung cấp tính năng điều hướng quay lại tuỳ chỉnh.

  2. Tắt OnBackPressedCallback khi bạn đã sẵn sàng dừng chặn thao tác quay lại.

  3. Dừng chặn các sự kiện quay lại qua OnBackPressed hoặc KeyEvent.KEYCODE_BACK.

  4. Đảm bảo bạn đã nâng cấp lên AndroidX Activity 1.6.0-alpha05.

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  5. Khi bạn đã di chuyển thành công ứng dụng của mình, hãy chọn sử dụng tính năng xem trước thao tác quay lại (như mô tả trên trang này) để xem ảnh động quay lại trang chủ của hệ thống.

Di chuyển ứng dụng dùng API điều hướng quay lại không được hỗ trợ sang API nền tảng

Nếu ứng dụng của bạn không thể dùng các thư viện AndroidX và thay vào đó triển khai hoặc tham chiếu đến thành phần điều hướng Quay lại tuỳ chỉnh bằng các API không được hỗ trợ, thì bạn phải di chuyển sang API nền tảng OnBackInvokedCallback.

Hãy hoàn thành các bước sau để di chuyển API không được hỗ trợ sang API nền tảng:

  1. Dùng API OnBackInvokedCallback mới trên các thiết bị chạy Android 13 trở lên, đồng thời dựa vào những API không được hỗ trợ trên các thiết bị chạy Android 12 trở xuống.

  2. Đăng ký logic quay lại tuỳ chỉnh trong OnBackInvokedCallback bằng onBackInvokedDispatcher. Đây là cách để ngăn hoạt động hiện tại hoàn tất và lệnh gọi lại của bạn sẽ có cơ hội phản ứng với thao tác Quay lại sau khi người dùng hoàn tất thao tác Quay lại của hệ thống.

  3. Huỷ đăng ký OnBackInvokedCallback khi đã sẵn sàng dừng chặn thao tác quay lại. Nếu không, người dùng có thể thấy hành vi không mong muốn khi sử dụng thao tác Quay lại của hệ thống – ví dụ: "bị nghẽn" giữa các khung hiển thị và buộc họ phải thoát ứng dụng của bạn.

    Sau đây là ví dụ về cách di chuyển logic ra khỏi onBackPressed:

    Kotlin

    @Override
    fun onCreate() {
        if (BuildCompat.isAtLeastT()) {
            onBackInvokedDispatcher.registerOnBackInvokedCallback(
                OnBackInvokedDispatcher.PRIORITY_DEFAULT
            ) {
                /**
                 * onBackPressed logic goes here. For instance:
                 * Prevents closing the app to go home screen when in the
                 * middle of entering data to a form
                 * or from accidentally leaving a fragment with a WebView in it
                 *
                 * Unregistering the callback to stop intercepting the back gesture:
                 * When the user transitions to the topmost screen (activity, fragment)
                 * in the BackStack, unregister the callback by using
                 * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
                 * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
                 */
            }
        }
    }

    Java

    @Override
    void onCreate() {
      if (BuildCompat.isAtLeastT()) {
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            () -> {
              /**
               * onBackPressed logic goes here - For instance:
               * Prevents closing the app to go home screen when in the
               * middle of entering data to a form
               * or from accidentally leaving a fragment with a WebView in it
               *
               * Unregistering the callback to stop intercepting the back gesture:
               * When the user transitions to the topmost screen (activity, fragment)
               * in the BackStack, unregister the callback by using
               * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
               * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
               */
            }
        );
      }
    }
  4. Dừng chặn các sự kiện quay lại qua OnBackPressed hoặc KeyEvent.KEYCODE_BACK đối với Android 13 trở lên.

  5. Sau khi di chuyển thành công ứng dụng của mình, hãy chọn sử dụng tính năng xem trước thao tác quay lại (theo mô tả trên trang này) để OnBackInvokedCallback có hiệu lực.

Bạn có thể đăng ký OnBackInvokedCallback bằng PRIORITY_DEFAULT hoặc PRIORITY_OVERLAY (không có trong OnBackPressedCallback tương tự của AndroidX). Việc đăng ký một lệnh gọi lại bằng PRIORITY_OVERLAY sẽ hữu ích trong một số trường hợp.

Điều này áp dụng khi bạn di chuyển từ onKeyPreIme() và lệnh gọi lại của bạn cần nhận cử chỉ quay lại thay vì IME đang mở. Khi mở, các IME sẽ đăng ký lệnh gọi lại bằng PRIORITY_DEFAULT. Đăng ký lệnh gọi lại của bạn bằng PRIORITY_OVERLAY để đảm bảo rằng OnBackInvokedDispatcher gửi cử chỉ quay lại đến lệnh gọi lại thay vì IME đang mở.

Chọn sử dụng tính năng xem trước thao tác quay lại

Khi đã xác định được cách cập nhật ứng dụng dựa vào trường hợp của bạn, hãy chọn sử dụng nhằm hỗ trợ tính năng xem trước thao tác quay lại.

Để chọn sử dụng, trong AndroidManifest.xml, trong thẻ <application>, hãy thiết lập cờ android:enableOnBackInvokedCallback thành true.

<application
    ...
    android:enableOnBackInvokedCallback="true"
    ... >
...
</application>

Nếu bạn không cung cấp một giá trị, thì giá trị mặc định sẽ là false và thực hiện các hành động sau:

  • Tắt ảnh động xem trước thao tác quay lại của hệ thống.
  • Bỏ qua OnBackInvokedCallback, nhưng các lệnh gọi OnBackPressedCallback vẫn hoạt động.

Chọn sử dụng tính năng ở cấp độ hoạt động

Kể từ Android 14, cờ android:enableOnBackInvokedCallback cho phép bạn chọn sử dụng ảnh động xem trước của hệ thống ở cấp hoạt động. Hành vi này giúp bạn dễ dàng quản lý việc di chuyển các ứng dụng lớn có nhiều hoạt động sang sử dụng tính năng xem trước thao tác quay lại. Với Android 15, tính năng xem trước thao tác quay lại không còn là tuỳ chọn dành cho nhà phát triển nữa. Ứng dụng có thể chọn sử dụng tính năng xem trước thao tác quay lại một cách đầy đủ hoặc ở cấp độ hoạt động.

Đoạn mã sau đây là ví dụ về cách sử dụng enableOnBackInvokedCallback để bật ảnh động quay lại trang chủ của hệ thống từ MainActivity:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

Trong ví dụ trước, việc thiết lập android:enableOnBackInvokedCallback=true cho ".SecondActivity" sẽ bật ảnh động hệ thống giữa nhiều hoạt động.

Khi sử dụng cờ android:enableOnBackInvokedCallback, hãy lưu ý những điểm cần cân nhắc sau đây:

  • Việc thiết lập android:enableOnBackInvokedCallback=false sẽ tắt ảnh động xem trước thao tác quay lại ở cấp hoạt động hoặc cấp ứng dụng, tuỳ thuộc vào nơi bạn thiết lập thẻ và hướng dẫn hệ thống bỏ qua các lệnh gọi đến API nền tảng OnBackInvokedCallback. Tuy nhiên, các lệnh gọi đến OnBackPressedCallback sẽ tiếp tục chạy vì OnBackPressedCallback có khả năng tương thích ngược và sẽ gọi onBackPressed API (không hỗ trợ trước Android 13).
  • Việc thiết lập cờ enableOnBackInvokedCallback ở cấp ứng dụng sẽ thiết lập giá trị mặc định cho tất cả hoạt động trong ứng dụng. Bạn có thể ghi đè giá trị mặc định đối với mỗi hoạt động bằng cách thiết lập cờ ở cấp hoạt động, như minh hoạ trong đoạn mã ví dụ trước.

Các phương pháp hay nhất về lệnh gọi lại

Dưới đây là các phương pháp hay nhất để dùng lệnh gọi lại hệ thống được hỗ trợ; BackHandler (dành cho Compose), OnBackPressedCallback hoặc OnBackInvokedCallback.

Xác định Trạng thái giao diện người dùng có thể bật và tắt mỗi lệnh gọi lại

Trạng thái giao diện người dùng (UI state) là thuộc tính mô tả giao diện người dùng. Bạn nên làm theo các bước tổng quan sau đây.

  1. Xác định Trạng thái giao diện người dùng có thể bật và tắt mỗi lệnh gọi lại.

  2. Xác định trạng thái đó bằng cách sử dụng loại phần tử giữ dữ liệu có thể ghi nhận được, chẳng hạn như StateFlow hoặc Trạng thái Compose, đồng thời bật hoặc tắt lệnh gọi lại khi trạng thái thay đổi.

Nếu ứng dụng của bạn từng liên kết logic quay lại với các câu lệnh có điều kiện, thì việc này có thể cho biết rằng bạn đang phản ứng với sự kiện quay lại sau khi sự kiện đã xảy ra. Tránh sử dụng mẫu này với các lệnh gọi lại mới hơn. Nếu có thể, hãy di chuyển lệnh gọi lại ra bên ngoài câu lệnh có điều kiện và thay vào đó, liên kết lệnh gọi lại đó với một loại phần tử giữ dữ liệu có thể ghi nhận được.

Sử dụng lệnh gọi lại hệ thống cho Logic giao diện người dùng

Logic giao diện người dùng (UI logic) cho biết cách hiển thị giao diện người dùng. Sử dụng lệnh gọi lại hệ thống để chạy logic giao diện người dùng, chẳng hạn như hiển thị cửa sổ bật lên hoặc chạy ảnh động.

Nếu ứng dụng của bạn bật lệnh gọi lại hệ thống, thì ảnh động dự đoán sẽ không chạy và bạn phải xử lý sự kiện quay lại. Đừng tạo lệnh gọi lại chỉ để chạy logic không phải giao diện người dùng.

Ví dụ: nếu bạn chỉ chặn các sự kiện quay lại để ghi nhật ký, hãy chuyển sang ghi lại trong vòng đời của Hoạt động hoặc Mảnh.

  • Đối với các trường hợp từ hoạt động đến hoạt động hoặc từ mảnh đến hoạt động, hãy ghi nhật ký nếu isFinishing trong onDestroytrue thuộc Vòng đời hoạt động.
  • Đối với các trường hợp từ mảnh đến mảnh, hãy ghi nhật ký nếu isRemoving trong onDestroy là đúng trong vòng đời khung hiển thị của Mảnh. Hoặc ghi nhật ký bằng các phương thức onBackStackChangeStarted hoặc onBackStackChangeCommitted trong FragmentManager.OnBackStackChangedListener.

Đối với trường hợp Compose, hãy ghi lại trong lệnh gọi lại onCleared() của ViewModel được liên kết với đích đến của Compose. Đây là tín hiệu tốt nhất để biết thời điểm một đích đến của Compose bị kéo ra khỏi ngăn xếp lui và bị huỷ.

Tạo lệnh gọi lại trách nhiệm duy nhất

Bạn có thể thêm nhiều lệnh gọi lại vào trình điều phối. Các lệnh gọi lại được thêm vào ngăn xếp, trong đó lệnh gọi lại được bật và thêm gần đây nhất sẽ xử lý cử chỉ quay lại tiếp theo với một lệnh gọi lại cho mỗi thao tác quay lại.

Bạn sẽ dễ dàng quản lý trạng thái bật của lệnh gọi lại nếu lệnh gọi lại đó chỉ có một trách nhiệm. Ví dụ:

Thứ tự của lệnh gọi lại trong ngăn xếp.
Hình 2. Sơ đồ ngăn xếp lệnh gọi lại.

Hình 2 cho thấy cách bạn có thể có nhiều lệnh gọi lại trong ngăn xếp, mỗi lệnh gọi lại chịu trách nhiệm cho một việc. Lệnh gọi lại chỉ chạy nếu các lệnh gọi lại ở trên trong ngăn xếp bị tắt. Trong ví dụ này, lệnh gọi lại "Are you sure..." (Bạn có chắc không...) được bật khi người dùng nhập dữ liệu vào một biểu mẫu và bị tắt nếu không. Lệnh gọi lại sẽ mở một hộp thoại xác nhận khi người dùng vuốt ngược để thoát khỏi biểu mẫu.

Lệnh gọi lại khác có thể bao gồm một thành phần Material hỗ trợ tính năng xem trước thao tác quay lại, một hiệu ứng chuyển đổi AndroidX sử dụng Progress API hoặc một lệnh gọi lại tuỳ chỉnh khác.

Lệnh gọi lại của childFragmentManager sẽ chạy nếu các lệnh gọi lại ở trên bị tắt và ngăn xếp lui cho FragmentManager này không trống, trong đó childFragmentManager được đính kèm trong một Mảnh. Trong ví dụ này, lệnh gọi lại nội bộ này bị tắt.

Tương tự, lệnh gọi lại nội bộ của supportFragmentManager sẽ chạy nếu các lệnh gọi lại ở trên bị tắt và ngăn xếp của lệnh gọi lại không trống. Hành vi này nhất quán khi sử dụng FragmentManager hoặc NavigationComponent để điều hướng, vì NavigationComponent dựa vào FragmentManager. Trong ví dụ này, lệnh gọi lại này sẽ chạy nếu người dùng không nhập văn bản vào biểu mẫu khiến lệnh gọi lại "Bạn có chắc chắn không..." bị tắt.

Cuối cùng, super.onBackPressed() là lệnh gọi lại cấp hệ thống, lệnh gọi lại này sẽ chạy lại nếu các lệnh gọi lại ở trên bị tắt. Để kích hoạt ảnh động hệ thống như quay lại màn hình chính, giữa các hoạt động và tác vụ, ngăn xếp lui của supportFragmentManager phải trống để lệnh gọi lại nội bộ của ngăn xếp đó bị tắt.

Kiểm thử ảnh động xem trước thao tác quay lại

Nếu vẫn sử dụng Android 13 hoặc Android 14, bạn có thể kiểm thử ảnh động quay lại màn hình chính trong Hình 1.

Để kiểm tra ảnh động này, hãy hoàn tất các bước sau:

  1. Trên thiết bị của bạn, hãy chuyển đến phần Cài đặt > Hệ thống > Tuỳ chọn cho nhà phát triển (Settings > System > Developer options).

  2. Chọn Ảnh động vuốt ngược dự đoán.

  3. Chạy ứng dụng đã cập nhật và dùng cử chỉ vuốt ngược để xem ứng dụng hoạt động.