Skip to content

BottomNavigation, FragmentManager has not been attached to a host

I have moved BottomNavigation codes from MainActivity to A class I have created for the BottomNaviction to make the code more organizing. When I moved the codes I got this error java.lang.RuntimeException: Unable to start activity ComponentInfo{com.moataz.mox/com.moataz.mox.ui.view.activity.MainActivity}: java.lang.IllegalStateException: FragmentManager has not been attached to a host. Short error message FragmentManager has not been attached to a host.

And The error In this line of code

// The error is here
final FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();

Here’s My BottomNavigation Class

public class BottomNavigation extends BottomNavigationView {

FragmentActivity fragmentActivity = new FragmentActivity();

final Fragment homeFragment = new HomeFragment();
final Fragment searchFragment = new SearchFragment();
final Fragment videosFragment = new VideosFragment();
final Fragment favouriteFragment = new FavouriteFragment();
final Fragment premiumFragment = new PremiumFragment();
// The error is here
final FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
Fragment mainFragment = homeFragment;

public BottomNavigation(@NonNull Context context) {
    super(context);
}

@SuppressLint("NonConstantResourceId")
public void initializeBottomNavigation() {
    // first one transaction to add each Fragment
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.fragment_layout, premiumFragment, "5").hide(premiumFragment);
    fragmentTransaction.add(R.id.fragment_layout, favouriteFragment, "4").hide(favouriteFragment);
    fragmentTransaction.add(R.id.fragment_layout, videosFragment, "3").hide(videosFragment);
    fragmentTransaction.add(R.id.fragment_layout, searchFragment, "2").hide(searchFragment);
    fragmentTransaction.add(R.id.fragment_layout, homeFragment, "1");
    // commit once! to finish the transaction
    fragmentTransaction.commit();

    // show and hide them when click on BottomNav items
    BottomNavigationView navigationView = findViewById(R.id.bottom_navigation);
    navigationView.setOnItemSelectedListener(item -> {
        // start a new transaction
        FragmentTransaction localFragmentTransaction = fragmentManager.beginTransaction();
        // TODO: ADD Animations
        switch (item.getItemId()) {
            case R.id.home_item:
                localFragmentTransaction.hide(mainFragment).show(homeFragment).commit();
                mainFragment = homeFragment;
                return true;

            case R.id.search_item:
                localFragmentTransaction.hide(mainFragment).show(searchFragment).commit();
                mainFragment = searchFragment;
                return true;

            case R.id.videos_item:
                localFragmentTransaction.hide(mainFragment).show(videosFragment).commit();
                mainFragment = videosFragment;
                return true;

            case R.id.saved_item:
                localFragmentTransaction.hide(mainFragment).show(favouriteFragment).commit();
                mainFragment = favouriteFragment;
                return true;

            case R.id.premium_item:
                localFragmentTransaction.hide(mainFragment).show(premiumFragment).commit();
                mainFragment = premiumFragment;
                return true;
        }
        return false;
    });
}

And here I haved Called my class and method In MainActivity

private void initializeBottomNavigation() {
BottomNavigation bottomNavigation = new BottomNavigation(this);
bottomNavigation.initializeBottomNavigation();

}

I have tried to find a sloution and anderstand the error but I didn’t found sothing In my case. So what is the problem here and How can I fix It?

Answer

You cannot make a new instance of an activity; activity instances are built only by Android itself. The only thing you can do in order to obtain an activity reference is to use an existing one.

public class BottomNavigation extends BottomNavigationView {

    final FragmentActivity fragmentActivity;
    ...
    final FragmentManager fragmentManager;
    
    public BottomNavigation(@NonNull Context context, @NonNull FragmentActivity activity) {
        super(context);
        fragmentActivity = activity;
        fragmentManager = fragmentActivity.getSupportFragmentManager();
    }

    ...
}

And pass your existing reference of your activity:

private void initializeBottomNavigation() {
    FragmentActivity activity = this; // Or your activity reference
    BottomNavigation bottomNavigation = new BottomNavigation(this, activity);
    bottomNavigation.initializeBottomNavigation();
}

Note that you still need to attach your BottomNavigation to a view parent in the activity to make it visible.