Đích đến hoạt động

Trong biểu đồ điều hướng, đích đến có thể là một hoạt động. Mặc dù phương pháp hay nhất là nên có một hoạt động duy nhất trong ứng dụng của bạn, nhưng ứng dụng thường dùng các hoạt động riêng biệt cho các thành phần hoặc màn hình khác nhau trong ứng dụng. Đích đến hoạt động có thể hữu ích trong những trường hợp như vậy.

Compose và Kotlin DSL

Việc thêm một đích đến hoạt động vào biểu đồ điều hướng về cơ bản giống nhau trong cả Compose và khi dùng Kotlin DSL với các mảnh. Điều này là do khi chuyển NavGraph đến thành phần kết hợp NavHost, bạn sẽ dùng cùng một hàm lambda createGraph().

Để biết thêm thông tin, hãy xem bài viết Tạo biểu đồ theo phương thức lập trình bằng Kotlin DSL.

XML

Việc tạo đích đến hoạt động tương tự như việc tạo đích đến mảnh. Tuy nhiên, bản chất của đích đến hoạt động lại rất khác.

Theo mặc định, thư viện Điều hướng đính kèm NavController vào một bố cục Activity còn biểu đồ điều hướng đang hoạt động thì thuộc phạm vi của Activity đang hoạt động. Nếu người dùng chuyển đến một Activity khác, thì biểu đồ điều hướng hiện tại không còn thuộc phạm vi đó nữa. Tức là đích đến Activity nên được coi là một điểm cuối trong biểu đồ điều hướng.

Để thêm một đích đến, hãy chỉ định đích đến Activity đó kèm theo tên lớp đủ điều kiện:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/simpleFragment">

    <activity
        android:id="@+id/sampleActivityDestination"
        android:name="com.example.android.navigation.activity.DestinationActivity"
        android:label="@string/sampleActivityTitle" />
</navigation>

XML này tương đương với lệnh gọi startActivity() sau:

Kotlin

startActivity(Intent(context, DestinationActivity::class.java))

Java

startActivity(new Intent(context, DestinationActivity.class));

Có thể có những trường hợp mà phương pháp này không phù hợp. Ví dụ: có thể bạn không có phần phụ thuộc thời gian biên dịch trên lớp hoạt động hoặc có thể bạn muốn chọn cấp độ gián tiếp thông qua ý định ngầm ẩn. intent-filter trong mục kê khai của đích đến Activity cho bạn biết cách định hình cấu trúc cho đích đến Activity.

Ví dụ: hãy xem xét tệp kê khai sau:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.navigation.activity">
    <application>
        <activity android:name=".DestinationActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <data
                    android:host="example.com"
                    android:scheme="https" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Bạn cần định cấu hình đích đến Activity tương ứng bằng các thuộc tính actiondata khớp với các giá trị trong mục kê khai:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="${applicationId}" />
</navigation>

Thao tác chỉ định targetPackage cho applicationId hiện tại sẽ giới hạn phạm vi của ứng dụng hiện tại, bao gồm cả ứng dụng chính.

Bạn cũng có thể dùng chính cơ chế này cho trường hợp bạn muốn một ứng dụng cụ thể trở thành đích đến. Ví dụ sau đây xác định đích đến là một ứng dụng có applicationIdcom.example.android.another.app.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="com.example.android.another.app" />
</navigation>

Đối số động

Các ví dụ trước dùng URL cố định để di chuyển đến đích. Cũng có thể bạn phải hỗ trợ các URL động, trong đó thông tin bổ sung được gửi dưới dạng một phần của URL. Ví dụ: bạn có thể gửi mã nhận dạng người dùng trong một URL có định dạng giống như sau https://example.com?userId=<actual user ID>.

Trong trường hợp này, thay vì thuộc tính data, hãy dùng dataPattern. Sau đó, bạn có thể cung cấp đối số để thay thế cho phần giữ chỗ đã đặt tên trong giá trị dataPattern:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:dataPattern="https://example.com?userId={userId}"
        app:targetPackage="com.example.android.another.app">
        <argument
            android:name="userId"
            app:argType="string" />
    </activity>
</navigation>

Trong ví dụ này, bạn có thể chỉ định giá trị userId bằng Safe Args hoặc bằng Bundle:

Kotlin

navController.navigate(
    R.id.localDestinationActivity,
    bundleOf("userId" to "someUser")
)

Java

Bundle args = new Bundle();
args.putString("userId", "someUser");
navController.navigate(R.id.localDestinationActivity, args);

Ví dụ này thay thế someUser bằng {userId} và tạo ra giá trị URI https://example.com?userId=someUser.