Cung cấp tính năng điều hướng quay lại tuỳ chỉnh

Tính năng điều hướng quay lại là khả năng người dùng di chuyển ngược lại thông qua lịch sử màn hình truy cập trước đó. Tất cả thiết bị Android đều cung cấp nút Quay lại cho loại điều hướng này, vì vậy bạn không nên thêm nút Quay lại vào giao diện người dùng của ứng dụng. Tuỳ vào thiết bị Android của người dùng, nút này có thể là nút vật lý hoặc nút phần mềm.

Android duy trì một ngăn xếp lui các đích đến khi người dùng di chuyển trong toàn bộ ứng dụng. Điều này thường cho phép Android điều hướng chính xác đến các đích đến trước đó khi nhấn nút Quay lại. Tuy nhiên, trong một số trường hợp, có thể ứng dụng cần phải triển khai thao tác Quay lại để mang lại trải nghiệm người dùng tốt nhất. Ví dụ: khi sử dụng WebView, bạn có thể ghi đè hành vi mặc định của nút Quay lại để cho phép người dùng quay lại thông qua nhật ký duyệt web thay vì các màn hình trước đó trong ứng dụng.

Triển khai tính năng điều hướng quay lại tuỳ chỉnh

ComponentActivity, lớp cơ sở cho FragmentActivityAppCompatActivity cho phép kiểm soát hành vi của nút Quay lại bằng cách sử dụng OnBackPressedDispatcher mà bạn có thể truy xuất bằng cách gọi getOnBackPressedDispatcher().

OnBackPressedDispatcher kiểm soát cách gửi các sự kiện nút Quay lại đến một hoặc nhiều đối tượng OnBackPressedCallback. Hàm khởi tạo cho OnBackPressedCallback lấy giá trị boolean làm trạng thái kích hoạt ban đầu. Chỉ khi một lệnh gọi lại được kích hoạt (tức là isEnabled() trả về true), thì trình điều phối mới gọi phương thức handleOnBackPressed() của lệnh gọi lại để xử lý sự kiện cho nút Quay lại. Bạn có thể thay đổi trạng thái bật bằng cách gọi setEnabled().

Lệnh gọi lại được thêm qua các phương thức addCallback. Bạn nên sử dụng phương thức addCallback(). Phương thức này sẽ lấy LifecycleOwner. Điều này đảm bảo OnBackPressedCallback chỉ được thêm khi LifecycleOwner có giá trị là Lifecycle.State.STARTED. Hoạt động này cũng xoá các lệnh gọi lại đã đăng ký khi LifecycleOwner liên kết với các lệnh gọi lại này bị huỷ. Điều này giúp ngăn chặn việc rò rỉ bộ nhớ và đảm bảo sử dụng phù hợp các lệnh gọi lại trong mảnh hoặc chủ sở hữu vòng đời khác có thời gian hoạt động ngắn hơn.

Dưới đây là ví dụ về cách triển khai lệnh gọi lại:

Kotlin

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback will only be called when MyFragment is at least Started.
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

Bạn có thể cung cấp nhiều lệnh gọi lại qua addCallback(). Khi thực hiện việc này, các lệnh gọi lại được gọi theo thứ tự ngược lại khi chúng được thêm vào - trong đó hàm được thêm vào sau cùng sẽ được dùng để xử lý sự kiện nút Quay lại. Ví dụ: nếu bạn đã thêm ba lệnh gọi lại có tên one, twothree theo thứ tự, thì các lệnh gọi lại đó sẽ được gọi theo thứ tự tương ứng là three, two, và one.

Lệnh gọi lại tuân theo mẫu Chuỗi trách nhiệm. Mỗi lệnh gọi lại trong chuỗi chỉ được gọi nếu hàm trước đó không được bật. Điều này có nghĩa là trong ví dụ trước đó, lệnh gọi lại two sẽ chỉ được gọi nếu bạn không bật lệnh gọi lại three. Lệnh gọi lại one sẽ chỉ được gọi nếu lệnh gọi lại two không được bật, v.v.

Lưu ý khi được thêm quaaddCallback(), lệnh gọi lại không được thêm vào chuỗi trách nhiệm cho đến khi LifecycleOwner nhập trạng thái Lifecycle.State.STARTED.

Bạn nên thay đổi trạng thái bật trên OnBackPressedCallback cho các thay đổi tạm thời vì chế độ này sẽ duy trì thứ tự mô tả ở trên. Điều này rất quan trọng khi đăng ký lại các lệnh gọi lại trên nhiều chủ sở hữu vòng đời lồng nhau.

Tuy nhiên, trong trường hợp muốn xoá hoàn toàn OnBackPressedCallback, bạn nên gọi remove(). Việc này thường không cần thiết, tuy nhiên vì các lệnh gọi lại sẽ tự động bị xoá khi LifecycleOwner được liên kết bị huỷ kích hoạt.

Hoạt động OnBackpressed()

Nếu đang dùng onBackPressed() để xử lý các sự kiện Nút quay lại, bạn nên sử dụng OnBackPressedCallback. Tuy nhiên, các quy tắc sau sẽ được áp dụng nếu bạn không thể thực hiện thay đổi này:

  • Tất cả các lệnh gọi lại đã đăng ký qua addCallback đều được đánh giá khi bạn gọi super.onBackPressed().
  • Trong Android 12 (API cấp 32) trở xuống, onBackPressed luôn được gọi bất kể mọi bản sao đã đăng ký của OnBackPressedCallback.