it-swarm.com.de

Komponente für Navigationsarchitektur - Übergabe von Argumentdaten an startDestination

Ich habe eine Aktivität A, bei der die Aktivität B einige Intent-Daten überträgt. Übung B Hosten eines Navigationsdiagramms aus der neuen Komponente "Navigationsarchitektur". Ich möchte diese Absichtsdaten als Anfangspunkt an das Fragment startDestination übergeben, wie dies zu tun ist.

17

OK, ich habe dank Ian Lake vom Google-Team eine Lösung für dieses Problem gefunden. Angenommen, Sie haben eine Aktivität A, die Aktivität B mit Absichtsdaten startet, und Sie möchten diese Daten in startDestination abrufen. Hier haben Sie zwei Optionen, wenn Sie sichere Argumente verwenden, was in meinem Fall möglich ist

StartFragmentArgs.fromBundle(requireActivity().intent?.extras)

die Argumente aus der Absicht zu lesen. Wenn Sie keine sicheren Argumente verwenden, können Sie die Daten aus dem Bundle mit Ihrer eigenen requireActivity().intent?.extras extrahieren, wodurch ein Bundle zurückgegeben wird, das Sie anstelle der fragment getArguments() -Methode verwenden können. Das ist es, ich versuche es und alles funktioniert gut.

8

TLDR: Sie müssen das Diagramm manuell aufblasen, die Schlüssel/Werte zu den defaultArgs hinzufügen und das Diagramm auf die Variable navController setzen. 

Schritt 1

In der Dokumentation werden Sie aufgefordert, das Diagramm im <fragment>-Tag im Layout Ihrer Activity festzulegen. So etwas wie:

<fragment
    Android:id="@+id/navFragment"
    Android:name="androidx.navigation.fragment.NavHostFragment"
    app:graph="@navigation/nav_whatever"
    app:defaultNavHost="true"
    />

REMOVE die Zeile mit dem graph=.

Schritt 2

Pumpen Sie das Diagramm in der Aktivität, die Ihre NavHostFragment anzeigt, folgendermaßen auf:

val navHostFragment = navFragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_whatever)

Dabei ist navFragment die ID, die Sie Ihrem Fragment in XML gegeben haben, wie oben.

Schritt 3 [Entscheidend!]

Erstellen Sie ein Bündel für die Argumente, die Sie an Ihr startDestination-Fragment übergeben möchten, und fügen Sie es den Standardargumenten des Diagramms hinzu:

val bundle = Bundle()
// ...add keys and values
graph.addDefaultArguments(bundle)

Schritt 4

Legen Sie das Diagramm auf der Hostvariable navController fest:

navHostFragment.navController.graph = graph
14
Elliot Schrock

Ich denke, das hat sich mit der Version 1.0.0 wieder geändert. Und Google hat diese Informationen in der offiziellen Dokumentation sehr gut versteckt. Zumindest hatte ich Probleme, es zu finden, bin aber im Handbuch Zur Navigationskomponente migrieren darauf gestoßen. Wie Sie Argumente an das Startziel übergeben, erfahren Sie hier:

https://developer.Android.com/guide/navigation/navigation-migrate#pass_activity_destination_args_to_a_start_destination_fragment

Zusamenfassend

  1. Sie müssen die Navigationsgrafik programmatisch einstellen:
findNavController(R.id.main_content)
                .setGraph(R.navigation.product_detail_graph, intent.extras)
  1. Legen Sie das Diagramm nicht in der NavHostFragment-XML-Deklaration fest.
  2. Lesen Sie die Extras auf der Empfängerseite:
val args by navArgs<ProductDetailsArgs>()  
val productId = args.productId

Update: Laut Google fehlt in der Tat die offizielle Dokumentation zur Übergabe von Argumenten an das ursprüngliche Navigationsziel. Hoffentlich wird dies bald als Teil der Dokumentation der Navigationskomponente hinzugefügt.

5
Johan Paul

Es wurde in 1.0.0-alpha07 behoben. Siehe Detail.

Die Lösung ähnelt der Antwort von Elliot Schrock, wird jedoch von offiziellen APIs verpackt.

Wir müssen NavHostFragment oder graph manuell aufblasen

Benutzen

NavHostFragment.create(R.navigation.graph, args)

Oder

navController.setGraph(R.navigation.graph, args)

Die args sind die Daten, die an das Startziel übergeben werden sollen.

2
HvSimon

Zum Zeitpunkt des Schreibens dieser Antwort verwende ich Navigation 2.2.0-alpha01

Wenn Sie einige Daten direkt als Argumente aus der Host-Aktivität an das Startziel übergeben möchten, müssen Sie das Navigationsdiagramm Ihres Hosts in der onCreate () -Methode der Host-Aktivität wie folgt manuell festlegen:

Holen Sie sich Ihren navController:

val navController by lazy { findNavController(R.id.<your_nav_Host_id>) }

Dann in der Host-Aktivität onCreate()

val bundle = Bundle()
bundle.putString("some_argument", "some_value")
navController.setGraph(R.navigation.<you_nav_graph_xml>, bundle)

Oder wenn Sie die gesamten Intent-Extras so weitergeben möchten, wie sie sich für das startDestination ergeben:

navController.setGraph(R.navigation.<you_nav_graph_xml>, intent.extras)

Da intent.extras Nur Bundle zurückgeben würde

Wenn Sie das Navigationsdiagramm mit der setGraph () -Methode festlegen, sollten Sie das Attribut app: NavGraph in der NavHostFragment-Definition nicht festlegen, da dies zum zweimaligen Aufblasen und Festlegen des Navigationsdiagramms führt.

Während Sie diese Argumente in Ihrem startDestination-Fragment lesen:

Wenn Sie das Safe Args Plugin verwenden (was sehr empfohlen wird), dann in Ihrem Fragment:

private val args by navArgs<DummyFragmentArgs>()

Das Safe Args-Plugin generiert eine Args-Klasse, indem Args an Ihren Fragmentnamen angehängt wird. Wenn Ihr Fragment beispielsweise DummyFragment heißt, würde Safe Args eine Klasse mit dem Namen DummyFragmentArgs generieren.

dabei ist navArgs<> eine Erweiterungsfunktion, die in Android KTX definiert ist

Wenn Sie nicht Android KTX verwenden, können Sie das args-Objekt wie folgt abrufen:

val args = DummyFragmentArgs.fromBundle(arguments!!)

Sobald Sie das arguments-Objekt erworben haben, können Sie einfach Ihre Argumente abrufen:

args.someArgument

Beachten Sie, wie wir "some_argument" Als Argument übergeben haben und es mit Safe Args als someArgument lesen

Wenn Sie Safe Args nicht verwenden (es gibt jedoch keinen Grund, es nicht zu verwenden), können Sie folgendermaßen auf Ihre Argumente zugreifen:

arguments?.getString("some_argument")

All dies wird in der Dokumentation zu Migrate to Navigation Component hier dokumentiert: https://developer.Android.com/guide/navigation/navigation-migrate#pass_activity_destination_args_to_a_start_destination_fragment

0
Praveen Singh

Also für die Leute, die immer noch damit zu kämpfen haben. Ich habe einen anderen Weg gefunden, dies ohne Safe-Args und einen Schritt mit @ Elliot's Answer zu tun.

Nehmen wir an, Sie haben in Aktivität B einige Argumente von Aktivität A erhalten und Ihre Aktivität B hat ein Fragment startDestination, mit dem Sie den Nav-Controller wie folgt initialisieren:

navController = Navigation.findNavController(this, R.id.detailFragment);

vom Nav-Controller aus haben Sie Zugriff auf Ihr Diagramm, das Sie wie folgt in XML festgelegt haben, und Sie können die Argumente in den defaultArguments festlegen:

navController.getGraph().addDefaultArguments(extras);

Hinweis: Dadurch werden auch die Werte der Schlüssel aktualisiert, wenn sie bereits in der Diagramm-XML vorhanden sind.

Jetzt müssen Sie in Ihrem Fragment die Standardargumente aus Ihrem NavHostFragment wie folgt finden:

Bundle defaultArguments = NavHostFragment.findNavController(this).getGraph().getDefaultArguments();

und du wirst die Werte dort haben. Ich weiß nicht, warum @Elliot es für entscheidend hält, aber es sollte der Weg sein?

UPDATE alpha09: AddDefault-Argument wird in dieser Version nicht mehr unterstützt. Sie müssen NavArgument verwenden

0
Dr. aNdRO