Search code examples
androidandroid-jetpackandroid-jetpack-navigation

Android Navigation for infinite Fragment


Must the target Fragment be registered in the navigation graph? For example, if I want to display a multi-level directory through Fragments, and each Fragment shows one directory, then I cannot register all the Fragments in the navigation view, because I can’t know how many Fragments are needed.
How should I do?

------- add --------

Maybe I did not describe my problem clearly, My current needs are shown below:

this is my needs

Now I use ViewPager and FragmentStatePagerAdapter to dynamically add and delete fragments, but I want to migrate to Navigation, I don’t know if there is a way。


Solution

  • You should only have one DirectoryFragment in your navigation graph. That fragment would have an argument that indicates what directory should be shown:

    <fragment android:id="@+id/directory_fragment"
        android:name="com.example.DirectoryFragment">
        <argument
            android:name="directory"
            app:argType="string"
            android:defaultValue="/" />
    </fragment>
    

    Then, you can navigate using the id:

    File directory = ...
    directoryButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Bundle arguments = new Bundle();
            arguments.putString("directory", directory.getAbsolutePath());
            Navigation.findNavController(view).navigate(
                R.id.directory_fragment, arguments);
        }
    });
    

    By calling navigate(), a new instance of your DirectoryFragment is created and added to the back stack, showing the directory you pass in as an argument.

    This is the bare minimum of what you need. It is strongly recommended that you connect your destinations via actions, which allows you to add transitions between your destinations and enables using Safe Args to add type safety to your navigate() calls.

    This would allow you to write something like:

    <fragment android:id="@+id/directory_fragment"
        android:name="com.example.DirectoryFragment">
        <argument
            android:name="directory"
            app:argType="string"
            android:defaultValue="/" />
        <action android:id="@+id/show_subdirectory"
            app:destination="@+id/directory_fragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"/>
    </fragment>
    

    And navigate via:

    File directory = ...
    directoryButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Navigation.findNavController(view).navigate(
                DirectoryFragmentDirections.showSubdirectory()
                    .setDirectory(directory.getAbsolutePath()));
        }
    });