Компонент навигации Android передает аргумент с помощью safeArgs и глубокой ссылки

У меня есть навигационный xml для функции, как показано ниже:

<?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_featureB.xml"
    app:startDestination = "@id/FragmentB">

    <fragment
        android:id = "@+id/FragmentB"
        android:name = "FragmentB"
        android:label = "FragmentB">
        <deepLink app:uri = "App://FragmentB" />
    </fragment>
</navigation>

В моем фрагменте FeatureA я делаю следующее:

val uri = Uri.parse("App://FragmentB")
findNavController().navigate(uri)

Я знаю, как использовать safeArgs без глубокой ссылки. Как передать данные другой функции с помощью глубокой ссылки?

7
0
8 726
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете сделать следующее

Сначала добавьте аргумент в navigation.xml

<?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_featureB.xml"
    app:startDestination = "@id/FragmentB">

    <fragment
        android:id = "@+id/FragmentB"
        android:name = "FragmentB"
        android:label = "FragmentB">
        <argument
            android:name = "yourarg"
            android:defaultValue = "Argument Default Value"/>
        <deepLink app:uri = "App://FragmentB/{yourarg}" />
    </fragment>
</navigation>

Тогда вы можете назвать это так

val args = Bundle()
args.putString("yourarg", "Argument Value")

val deeplink = findNavController().createDeepLink()
               .setDestination(R.id.FragmentB)
               .setArguments(args)
               .createPendingIntent()
val builder = NotificationCompat.Builder(
                context, "deeplink")
                .setContentTitle("Deep link with data")
                .setContentText("Deep link with data to Android")
                .setSmallIcon(R.drawable.ic_android)
                .setContentIntent(deeplink)
                .setAutoCancel(true)
val notificationManager =
                context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, builder.build())

ОТРЕДАКТИРОВАНО

Без уведомления

Сначала добавьте аргумент в navigation.xml

<?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_featureB.xml"
    app:startDestination = "@id/FragmentB">

    <fragment
        android:id = "@+id/FragmentB"
        android:name = "FragmentB"
        android:label = "FragmentB">
        <argument
            android:name = "yourarg"
            android:defaultValue = "Argument Default Value"/>
        <deepLink app:uri = "App://FragmentB/{yourarg}" />
    </fragment>
</navigation>

Тогда вы можете назвать это так

val uri = Uri.parse("App://FragmentB/yourarg")
findNavController().navigate(uri)

Затем вы можете получить аргумент с помощью этого кода

val argument = arguments?.getString("yourarg")

// Or with Safe Args

val safeArgs: FragmentBArgs by navArgs()
val yourarg = safeArgs.yourarg

Использованная литература : https://codelabs.developers.google.com/codelabs/android-navigation#9

Неужели нет другого пути? Я просто хочу открыть фрагмент в другой функции в том же приложении, и нужны ли мне для этого уведомления?

Ma2340 14.12.2020 09:35

пожалуйста, проверьте мой обновленный ответ, я предоставил способ без использования уведомления

Franz Andel 14.12.2020 11:05

Это помогает большое спасибо :) Я принял ответ. Но есть ли возможность использовать safeArgs с глубокими ссылками?

Ma2340 14.12.2020 11:16

Конечно, рад, что это помогло :) Да, можно использовать safeArgs, я снова обновил ответ :)

Franz Andel 14.12.2020 11:26

Конечно, без проблем :)

Franz Andel 14.12.2020 11:28

Это касается только строковых типов данных, но во многих приложениях нам нужно передавать пользовательские объекты с помощью глубокой ссылки. Можем ли мы что-нибудь сделать?

Aayush Goyal 07.04.2022 22:13

Приведенные выше ответы показывают, как работать со строковыми типами данных. Но если вы хотите передать пользовательские объекты, безопасные аргументы также подойдут;

<fragment
    android:id = "@+id/verification_fragment"
    android:name = "com.appname.ui.verification.VerificationFragment"
    android:label = "VerificationFragment">
    <argument
        android:name = "verificationType"
        android:defaultValue = "PHONE"
        app:argType = "com.appname.core.model.VerificationType" />
    <deepLink app:uri = "android-app://com.appname/verification_fragment?verificationType = {verificationType}" />
</fragment>

Передать пользовательские атрибуты в deeplink;

            val request = NavDeepLinkRequest.Builder
            .fromUri("android-app://appname/verification_fragment?verificationType=${VerificationType.MAIL}".toUri())
            .build()
        findNavController().navigate(request)

Чтение атрибутов из фрагментов назначения;

private val args: VerificationFragmentArgs by navArgs()

args.verificationType

Неа. это приведет к тому, что «Parcelables не поддерживает значения по умолчанию. Аргумент глубокой ссылки для навигации Android» для пользовательского атрибута лучше сначала преобразовать его в JSON, передать его в URI, а затем преобразовать обратно в объект.

wood wood 23.02.2023 07:53

Другие вопросы по теме