Sneha Bansal
Sneha Bansal

Reputation: 941

Send call back to previous fragment with data using navigation graph

I am using navigation graph for the first time so need help regarding the same.

In my application I have MainActivity with 5 nested graphs.

<?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/main_navigation" app:startDestination="@+id/home_navigation"> <include app:graph="@navigation/home_navigation" /> <include app:graph="@navigation/explorer_navigation" /> <include app:graph="@navigation/favourite_navigation" /> <include app:graph="@navigation/server_navigation" /> <include app:graph="@navigation/settings_navigation" /> </navigation>

Now, I need suggestion for below things

1.Need to implement a common error screen for multiple error types with an action button.

2.Need to provide call back from this error screen on pressing action button with some data on previous screen

3.I also want to send action from child navigation to parent navigation to navigate on other destination.

Thankyou in advance.

For 1st, Currently I have added error fragment for separately for each nested graph which added overhead to handle error page separately.

`

<action android:id="@+id/action_global_fragment_settings"
    app:destination="@id/fragment_settings"/>

<fragment
    android:id="@+id/fragment_settings"
    android:name="com.xyz.android.ui.settings.SettingsBaseFragment"
    android:label="@string/title_settings">
    <action
        android:id="@+id/action_fragment_settings_to_fragment_error"
        app:destination="@id/fragment_error" />
    <action
        android:id="@+id/action_fragment_settings_to_settings_details_fragment"
        app:destination="@id/fragment_settings_details" />
</fragment>
<fragment
    android:id="@+id/fragment_error"
    android:name="com.xyz.android.ui.nodata.ErrorBaseFragment">
    <argument
        android:name="title"
        android:defaultValue="NO_DATA"
        app:argType="string" />
    <argument
        android:name="errorType"
        app:argType="com.xyz.android.ui.nodata.EnumErrorType"
        android:defaultValue="NO_DATA" />
</fragment>

<fragment
    android:id="@+id/fragment_settings_details"
    android:name="com.xyz.android.ui.settings.SettingsBaseFragmentDetails">
    <argument
        android:name="settingsConfig"
        app:argType="com.xyz.android.ui.settings.beans.SettingsConfigHelper$SettingsConfig" />
</fragment>

`

For 2nd, Still I have not found way to send call back to previous fragment with data.

For 3rd, I have used shared view model but need better approach.

Upvotes: 0

Views: 493

Answers (2)

C.F.G
C.F.G

Reputation: 1463

Have you looked at Pass data between destinations?

by clicking on each fragment in navigation graph window, you can define arguments of arbitrary type in right tools panel (Arguments). For more deatials see Android Navigation Component : Pass value (arguments) in fragments

enter image description here:

Upvotes: 0

Gary Archer
Gary Archer

Reputation: 29291

There are a couple of techniques I use to manage navigation, while keeping code fairly simple:

ERROR SCREENS

I find separation of error summary and detail useful. My demo app renders an error summary fragment in the containing fragment, to avoid the need for navigation just to present an error. In my demo app this renders a red link:

error summary

When the red text is clicked, an error details fragment is displayed as a modal dialog, which again avoids navigation, and makes it easy to return a result to the current fragment:

error details

NAVIGATION FROM A FRAGMENT

A fragment can ask the navigation system to update the current location, as in this example code:

val args = Bundle()
args.putString(Constants.ARG_COMPANY_ID, viewModelItem.company.id.toString())
findNavController().navigate(R.id.transactions_fragment, args)

EVENTS

When navigation gets complex, a publish subscribe model of communication is often useful. For example, I like this EventBus project. Any view can register for events like this:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    EventBus.getDefault().register(this)
}

override fun onDestroyView() {
    super.onDestroyView()
    EventBus.getDefault().unregister(this)
}

@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: ReloadDataEvent) {
    this.reloadData(event.someData)
}

Then any other view can raise the event, when something happens that means other views should be informed, eg to reload their data. The code needed is pretty simple also.

EventBus.getDefault().post(ReloadDataEvent(someData))

DEMO APP

If any of this is useful you can run my demo app and adapt its code to your own preferences.

Upvotes: 1

Related Questions