IllegalStateException: Link does not have a NavController set

前端 未结 9 2192
故里飘歌
故里飘歌 2020-11-29 03:58

I\'m using Android Navigation Component for Navigation. I have a LoginFragment which has a button to transition to SignUpFragment. On clicking the button I\'m getting this e

相关标签:
9条回答
  • 2020-11-29 04:11

    I faced the same problem. So,instead of this,

    binding.signUpLink.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_loginFragment_to_signUpFragment, null));

    I used my NavHostFragment to find the NavHostFragment:

    Button button = (Button)findViewById(R.id.button);
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    Fragment navhost = getSupportFragmentManager().findFragmentById(R.id.fragment2);
                    NavController c = NavHostFragment.findNavController(navhost);
                    c.navigate(R.id.firstFragment);
    
    
                }
            });
    

    fragment2 is navhostfragmentID.

    0 讨论(0)
  • 2020-11-29 04:13

    I've done some research and found this Issue also on Google. So here's the official solution in Java:

    NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.nav_host_fragment);
    NavController navCo = navHostFragment.getNavController();
    

    and here in kotlin:

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    
    0 讨论(0)
  • 2020-11-29 04:13

    The reason is that the fragment view isn't available inside the Activity.onCreate() method if you're adding it using FragmentContainerView (or just a FrameLayout). The proper way to get the NavController in this case is to find the NavHostFragment and get the controller from it. See the issue and the explanation.

    override fun onCreate(savedInstanceState: Bundle?) {
       ...
    
       val navHostFragment = supportFragmentManager.findFragmentById(R.id.my_fragment_container_view_id) as NavHostFragment
       val navController = navHostFragment.navController
    }
    

    Don't use <fragment> instead of <androidx.fragment.app.FragmentContainerView> as some other answers suggest. See the comment from the Google team in the issue I mentioned above.

    You should always use FragmentContainerView. There are absolutely other fixes around window insets and layout issues that occur when a fragment's root layout is directly within other layouts such as ConstraintLayout, besides the underlying issues with the tag where fragments added via that tag go through lifecycle states entirely differently from the other Fragments added to the FragmentManager. The Lint check is there exactly because you absolutely should switch over to FragmentContainerView in all cases.

    There's also an announcement from AndroidDevSummit 2019 which explains why FragmentContainerView was introduced, and another thread on SO about the difference: <androidx.fragment.app.FragmentContainerView> vs as a view for a NavHost

    0 讨论(0)
  • 2020-11-29 04:14

    i faced this issue just now, but i was sure about my code and then realized that i have changed the location of the fragment from under the main package to another folder

    so i solved the issue with Build-> clean then Build ->make project to let the IDE to change its Directions class

    0 讨论(0)
  • 2020-11-29 04:15

    A weird thing happens to me, below code snippet was working on normal flow from Fragment1 to fragment2, but after coming to fragment1 and on again navigate fragment2, this was throwing the "Navigation controller not set for the view" error.

        binding.ivIcon.setOnClickListener(v -> {
                Openfragment2(v);});
    
    private void Openfragment2(View view) {
        Navigation.findNavController(binding.ivIcon).navigate(R.id.fragment2);
    
    }
    

    Here problem was in view, in findNavController need to pass the onclicked view.

    private void Openfragment2(View view) {
        Navigation.findNavController(view).navigate(R.id.fragment2);
    
    }
    
    0 讨论(0)
  • 2020-11-29 04:18

    Officially recommended solution

    Currently using the FragmentContainerView is not very friendly, you have to access it from the supportFragmentManager:

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    

    In my xml my FragmentContainerView looks like this:

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="parent"
        app:navGraph="@navigation/nav_graph"
        />
    

    This has been tested with androidx navigation version 2.3.0

    I've removed the old answer because it has been clarified by Google devs that it is not the recommended solution anymore. Thanks @Justlearnedit, for posting a comment allowing me to update this issue.

    0 讨论(0)
提交回复
热议问题