web-dev-qa-db-ger.com

So übergeben Sie ein Objekt des Typs "Parcelable" mithilfe des Navigations-Plugins "safeargs" an ein Fragment

Ich schreibe meine einfache UI-App für die Verwendung der Navigationsarchitekturkomponente. Ich muss einen Pojo übergeben, der Parcelable implementiert.

Jede Hilfe wäre dankbar.

8
Po10cio

Seit safe-args-gradle-plugin:1.0.0-alpha03 können Sie Parcelable-Objekte verwenden, indem Sie ihren vollständig qualifizierten Klassennamen verwenden: 

app:argType="com.example.app.model.Item"

Parcelable-Argumente werden jetzt unterstützt und verwenden einen vollständig qualifizierten Klassennamen für app: type. Der einzige unterstützte Standardwert ist "@null" ( https://issuetracker.google.com/issues/79563966 ).

Quelle: https://developer.Android.com/jetpack/docs/release-notes

15
Marius

Im Moment können Sie keine sicheren Argumente mit Typen außer integer, string, inferred und reference verwenden. Es gibt ein issue , das nach anderen Typen fragt.

Sie können jetzt normalerweise ein bundle übergeben, wenn Sie mit der navigate () -Methode zu einem Ziel navigieren:

var bundle = bundleOf("amount" to amount)
view.findNavController().navigate(R.id.confirmationAction, bundle)

Und Sie können die übliche getArguments (oder nur Argumente in kotlin) verwenden, um das abzurufen:

val tv = view.findViewById(R.id.textViewAmount)
tv.text = arguments.getString("amount")
5
Levi Moreira

Ich weiß, die Antwort ist bereits da, aber das kann jemandem helfen. Code snippet 

Fügen Sie in build.gradle diese Abhängigkeit hinzu 

ext{
     ...
     navigation_version = '1.0.0-alpha11'
}
dependencies {
     ...
     classpath "Android.Arch.navigation:navigation-safe-args-gradle-plugin:$navigation_version"
}

In app/build.gradle

apply plugin: 'androidx.navigation.safeargs'
...

In der Navigationsgrafik


 <fragment
            Android:id="@+id/source_fragment_id"
            Android:name="app.test.SourceFragment"
            Android:label="@string/source_fragment_label"
            tools:layout="@layout/source_fragment_layout">

         <action
                Android:id="@+id/action_source_fragment_to_destination_fragment"
                app:destination="@id/destination_fragment_id"
                ...
                />


</fragment>

<fragment
            Android:id="@+id/destination_fragment_id"
            Android:name="app.test.DestinationFragment"
            Android:label="@string/destination_fragment_label"
            tools:layout="@layout/destination_fragment_layout">

        <argument
                Android:name="variableName"
                app:argType="app.test.data.model.CustomModel" />

        ...

</fragment>

Hinweis: CustomModel sollte Parcelable oder Serializable sein.

Beim Navigieren zu diesem DestinationFragment von SourceFragment aus

val direction = SourceFragmentDirections.ActionSourceFragmentToDestinationFragment(customModel)
findNavController().navigate(direction)

Rufen Sie jetzt den Wert aus dem Bundle in DestinationFragment ab

...
import app.test.DestinationFragmentArgs.fromBundle

class DestinationFragment : Fragment() {
   val variableName by lazy {
       fromBundle(arguments!!).variableName
   }

   ...
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.e(DESTINATION_FRAGMENT_TAG,"onCreateView")

        //Can use CustomModel variable here i.e. variableName


   }

}
1
Suyash Chavan

Sie können boolean, reference, integer, long, string, enum, parcelable und sogar serializable verwenden. Aber vergiss den letzten ;-)

Verwenden Sie besser die neueste Plugin-Version safe-args-gradle-plugin:1.0.0-alpha08 und geben Sie den vollständig qualifizierten Klassennamen an:

<fragment
    ...>
    <argument
        Android:name="data"
        app:argType="com.example.ParcelableData" />
</fragment>

von deiner

package com.example

data class ParcelableData(val content: String) : Parcelable { ... }

Und Sie können Arrays aller argTypes senden:

<argument
        Android:name="data"
        app:argType="string[]" />
0
sbo3000