Fragment's id and tag are not set when using navigation component

Viewed 963

I have the problem that my fragment's id and tag are not set although I specify them in my 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_frag1">

    <fragment
        android:id="@+id/nav_frag1"
        android:tag="abcdef"
        android:name="org.example.myproject.MyFragment"
        android:label="@string/menu_frag1"
        tools:layout="@layout/fragment_frag1" />

    ...

</navigation>

When I try to access the id and tag programmatically in my fragment via this.getId() or this.getTag() the id is always the same very high integer for all fragments (a little smaller than max int) and the tag is null.

The navigation is put together in my main activity. The code is basically the example drawer navigation project created by Android Studio. I did not change anything about it.

public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.frag1, R.id.frag2, R.id.frag3)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

}

Am I missing something about the way the id and tag has to be set?

Edit: An example project that demonstrates the unexpected behavior can be found at https://github.com/flauschtrud/FragmentTagAndIdTest.

1 Answers

The fragment tag into a navigation tag it is a destination(Anatomy of a destination here), so you can define: id, name, label.

<navigation>
    <fragment></fragment>
</navigation>

Unlike fragment tag into a xml layout, where the implementation get the android:tag attr and uses it when inflates the Fragment from android:name.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   <fragment
      android:id="@+id/someFragment"
      android:tag="someTagNameToSomeFragment"
      android:name="com.somepackagename.SomeFragment"/>
</LinearLayout>

The same happens about the android:id, its the id resource for that destination, not the Fragment id. We have two ways to set an id for a Fragment, either from xml layout file (like example above) or through a transaction. From a transaction (commit kotlin extension from an Activity):

supportFragmentManager.commit { add(R.id.someFragment, SomeFragment()) }

I'm assuming that R.id.nav_host_fragment is the id that you give to NavHostFragment container (View) defined on xml layout. In this situation, each time you navigates to a new destination the before Fragment View is destroyed and the new Fragment and its View is created. The Fragment id on those situations will be R.id.nav_host_fragment (NavHostFragment container (View) id defined on xml layout).

Related