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 có nút Quay lại cho loại điều hướng này, vì vậy đừng 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 trong phần mềm.

Android duy trì một ngăn xếp lui của các đích đến khi người dùng di chuyển trong ứng dụng. Điều này 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 hành vi Quay lại riêng để 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 của nút Quay lại mặc định để 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.

Android 13 trở lên có tính năng xem trước thao tác quay lại cho các thiết bị Android. Để tìm hiểu thêm về tính năng này, hãy xem bài viết Hỗ trợ tính năng xem trước thao tác quay lại.

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. Khi bạn kích hoạt một lệnh gọi lại – tức là isEnabled() trả về true – trình điều phối sẽ gọi handleOnBackPressed() của lệnh gọi lại để xử lý sự kiện nút Quay lại. Bạn có thể thay đổi trạng thái đã kích hoạt đó bằng cách gọi setEnabled().

Lệnh gọi lại được thêm bằng 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 LifecycleOwner phù hợp với 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 is only 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 is only 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 bằng 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 với thứ tự bạn thêm chúng, trong đó lệnh gọi lại 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 lần lượt thêm 3 lệnh gọi lại có tên one, twothree, các lệnh gọi lại này sẽ được gọi theo thứ tự three, two 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 lệnh gọi lại trước đó không được kích hoạt. Điều này có nghĩa là trong ví dụ trước, lệnh gọi lại two chỉ được gọi nếu lệnh gọi lại three chưa được kích hoạt và lệnh gọi lại one chỉ được gọi nếu lệnh gọi lại two chưa được kích hoạt.

Lưu ý rằng khi thêm lệnh gọi lại bằng addCallback(), lệnh gọi lại sẽ không được thêm vào chuỗi trách nhiệm cho đến khi LifecycleOwner chuyển sang trạng thái Lifecycle.State.STARTED.

Bạn nên thay đổi trạng thái kích hoạt trên OnBackPressedCallback cho các thay đổi tạm thời, vì việc này sẽ duy trì thứ tự như 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.

Trong trường hợp muốn xoá hoàn toàn OnBackPressedCallback, bạn có thể gọi remove(). Việc này thường không cần thiết 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.