androidandroid-fragmentsandroid-architecture-navigation

Android Navigation Component : Pass value (arguments) in fragments


What I have done:

I have created Navigation Drawer Activity, As updated new format of Navigation Drawer Activity, As per new Android architecture, I got it with Navigation Component structure.

The NavigationView code with NavController and NavigationUI is below which is opening fragment when I click on any navigation item.

DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
        R.id.nav_home, R.id.nav_profile, R.id.nav_privacy_policy,
        R.id.nav_terms, R.id.nav_contact_us, R.id.nav_share, R.id.nav_send)
        .setDrawerLayout(drawer)
        .build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);

This is for nav_host_fragment:

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/mobile_navigation" />

The navigation is happening using this navigation/mobile_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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mobile_navigation"
    app:startDestination="@+id/nav_home">

    <fragment
        android:id="@+id/nav_home"
        android:name="com.sohamerp.marsremedies.fragment.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/nav_profile"
        android:name="com.sohamerp.marsremedies.fragment.ProfileFragment"
        android:label="@string/menu_my_profile"
        tools:layout="@layout/fragment_profile" />

    <fragment
        android:id="@+id/nav_privacy_policy"
        android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment"
        android:label="@string/menu_privacy_policy"
        tools:layout="@layout/fragment_privacy_policy" />

    <fragment
        android:id="@+id/nav_terms"
        android:name="com.sohamerp.marsremedies.fragment.TermsConditionFragment"
        android:label="@string/menu_terms"
        tools:layout="@layout/fragment_terms_condition" />

    <fragment
        android:id="@+id/nav_contact_us"
        android:name="com.sohamerp.marsremedies.fragment.ContactUsFragment"
        android:label="@string/menu_contact_us"
        tools:layout="@layout/fragment_terms_condition" />

</navigation>

What I want to do:

Now I want to pass some values as a bundle (arguments) in Fragment when it's called.

Scenario: I have two fragments PrivacyPolicyFragment and TermsConditionsFragment, In both fragments, I am just opening links inside WebView accordingly. So When I click on the menu item of Privacy Policy, I will pass a link related to the same.

In this new structure navigation/mobile_navigation.xml opening fragments, How can I pass arguments?

Any help?


Solution

  • So I forgot to go through this link : Define Destination Arguments

    But this answer helpful to all lazy peoples like me:

    Add dependency in project level build.gradle:

    classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0"
    

    Apply plugin in app level build.gradle:

    apply plugin: "androidx.navigation.safeargs"
    

    Using XML: predefined (static) value:

    In xml file of navigation /navigation/mobile_navigation.xml declare argument tag as below or you can design through this link:

    <fragment
        android:id="@+id/nav_privacy_policy"
        android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment"
        android:label="@string/menu_privacy_policy"
        tools:layout="@layout/fragment_privacy_policy" >
        <argument
            android:name="privacyPolicyLink"
            app:argType="string"
            android:defaultValue="http://sohamerp.com/avo/avo_privacy_policy.html"/>
    </fragment>
    
    <fragment
        android:id="@+id/nav_terms"
        android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment"
        android:label="@string/menu_terms"
        tools:layout="@layout/fragment_terms_condition" >
        <argument
            android:name="privacyPolicyLink"
            app:argType="string"
            android:defaultValue="http://sohamerp.com/avo/avo_privacy_policy.html"/>
    </fragment>
    

    Now you have to write code in your Fragment like:

    if(getArguments() != null) {
        // The getPrivacyPolicyLink() method will be created automatically.
        String url = PrivacyPolicyFragmentArgs.fromBundle(getArguments()).getPrivacyPolicyLink();
    }
    

    Hope it will helps you others.