Home > other >  NavHostFragment getActivity.getSupportFragmentManager is always null
NavHostFragment getActivity.getSupportFragmentManager is always null

Time:10-13

I have a FragmentContainerView in my activity_main

<androidx.fragment.app.FragmentContainerView
        android:id="@ id/main_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="1dp"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"/>

and in my fragment_login I try to go to another fragment by clicking the fab

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="localVariable"
            type="personal.net.handheldrfidreader.viewmodels.LoginViewModel"
            />
    </data>

    <androidx.coordinatorlayout.widget.CoordinatorLayout>
    
        ...
    
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@ id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:baselineAlignBottom="false"
            android:clickable="true"
            android:src="@drawable/ic_settings"
            app:fabSize="normal"
            app:layout_anchor="@id/appbar"
            app:layout_anchorGravity="end|bottom"
            android:layout_marginRight="30dp"
            android:backgroundTint="@color/light_orange"
            android:tint="@color/white"
            />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

I call the nav controller in the LoginFragment as so:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_login);
        viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
        binding.setLifecycleOwner(this);
        binding.setLocalVariable(viewModel);
    }


@Override
    public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setupButtons();
    }

private void setupButtons() {

        binding.fab.setOnClickListener(v -> {
            NavHostFragment navHostFragment = (NavHostFragment) getActivity().getSupportFragmentManager()
                    .findFragmentById(R.id.nav_graph);
            NavController navController = navHostFragment.getNavController();
            navController.navigate(R.id.action_loginFragment_to_settingsFragment);
        });
    }

but on

NavHostFragment navHostFragment = (NavHostFragment) getActivity().getSupportFragmentManager()
                        .findFragmentById(R.id.nav_graph);

I get a null value.

CodePudding user response:

Your FragmentContainerView has the id @ id/main_fragment and in your LoginFragment you are searching for a fragment with the id R.id.nav_graph. That is why you get a null value.

First change your id to nav_graph:

<androidx.fragment.app.FragmentContainerView
    android:id="@ id/nav_graph"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="1dp"
    app:navGraph="@navigation/nav_graph"
    app:defaultNavHost="true"/>

And then get your navController in LoginFragment with:

NavController navController = activity?.findNavController(R.id.nav_graph)

Now you should be able to navigate to SettingsFragment.

CodePudding user response:

In your case getActivity() returns null. Try following:

private AppCompatActivity activity;

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_login);
        viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
        binding.setLifecycleOwner(this);
        binding.setLocalVariable(viewModel);
    }

@Override
public void onAttach(Context context) {
    super.onAttach(activity);

if(context instanceof AppCompatActivity){
activity = ((AppCompatActivity) context)
}
}


@Override
    public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setupButtons();
    }

private void setupButtons() {

        binding.fab.setOnClickListener(v -> {
            NavHostFragment navHostFragment = (NavHostFragment) activity.getSupportFragmentManager()
                    .findFragmentById(R.id.nav_graph);
            NavController navController = navHostFragment.getNavController();
            navController.navigate(R.id.action_loginFragment_to_settingsFragment);
        });
  • Related