Update 2023-06-10:
Below is no longer working since androidx.navigation:navigation-fragment-ktx:2.6.0
Original post
I tried STAR_ZERO's solution https://github.com/STAR-ZERO/navigation-keep-fragment-sample for several hours and found it not working in my app first of all.
Finally succeeded to achieve what I wanted: My main Fragment in main Activity should not be re-created each time when navigating away and then back using NavigationBarView or BottomNavigationView.
Limitations:
- Works only exactly with the nav_graph's startDestination (here: app:startDestination="@id/nav_home"), Note: All other fragments require the<keep_state_fragment ...>too!
- Using setOnItemSelectedListener (NavigationBarView.OnItemSelectedListener listener) seems to conflict with the intention to not re-create a fragment
Using these versions:
dependencies {
   implementation "androidx.navigation:navigation-fragment-ktx:2.5.3"
   implementation "androidx.navigation:navigation-ui-ktx:2.5.3"
}
layout/activity_main.xml
...
<!-- Do NOT add app:navGraph="@navigation/nav_graph" -->
<androidx.fragment.app.FragmentContainerView 
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:defaultNavHost="true"        
...
navigation/nav_graph.xml
<navigation 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/nav_home">
<!-- ALL fragments must be keep_state_fragment,
     otherwise nav_home will not behave as keep_state_fragment -->
    <keep_state_fragment
        android:id="@+id/nav_home"
        ... />
    <keep_state_fragment
        android:id="@+id/nav_other"
        ... />
KeepStateNavigator.kt (yes ... nearly empty class)
@Navigator.Name("keep_state_fragment") // 'keep_state_fragment' is used in navigation/nav_graph.xml
class KeepStateNavigator(
    private val context: Context,
    private val manager: FragmentManager, // MUST pass childFragmentManager.
    private val containerId: Int
) : FragmentNavigator(context, manager, containerId) {
    
    /* NOTE: override fun navigate(...) is never called, so not needed */
}  
MainActivity.java
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    Fragment navHostFragment = getSupportFragmentManager()
                .findFragmentById(R.id.nav_host_fragment);
    FragmentManager childFragmentManager = navHostFragment.getChildFragmentManager();
    // Add our KeepStateNavigator to NavController's NavigatorProviders
    navController.getNavigatorProvider().addNavigator(
                    new KeepStateNavigator(this, childFragmentManager,
                            R.id.nav_host_fragment));
    // must be here, not in layout/activity_main.xml,
    // because we create KeepStateNavigator after NavigationBarView was inflated
    navController.setGraph(R.navigation.nav_graph);
    // Do NOT set a NavigationBarView.OnItemSelectedListener
    // Seems to conflict with the intention to not re-create Fragment
    // DO NOT: *NavigationBarView*.setOnItemSelectedListener(...);
    
    // Done.
    NavigationUI.setupWithNavController(navBarView, navController);
}