Search code examples
javaandroidgoogle-mapsandroid-fragmentsandroid-maps

MapFragment. When inflating a layout: java.lang.IllegalStateException: Fragment already added


I get the next error: java.lang.IllegalStateException: Fragment already added.

This is a layout getting inflated each time I change tab, as seen in this photo:

![FirstTab]http://prntscr.com/h4e8pc

![SecondTab]http://prntscr.com/h4ebyn

So i get the idea of the problem, but I've tried many ways to fix it with no result. I've tried to use .replace instead of .add, that way it doesnt crash but the map is not loaded. And also tried to delete the fragment as soon as I switch to that tab but the result is similar to the .replace one.

            case R.id.navigation_dashboard:

                frame = (FrameLayout) findViewById(R.id.content);
                frame.removeAllViewsInLayout();
                LayoutInflater.from(getApplicationContext())
                              .inflate(R.layout.activity_prueba_dashboard, frame, true);

                fragmentTransaction =
                        getFragmentManager().beginTransaction();
                fragmentTransaction.add(R.id.content2, mMapFragment);
                fragmentTransaction.commit();
                mMapFragment.getMapAsync(my_maps_class);

Solution

  • I believe it's much cleaner to use viewpager in that situation. Check this code :

    public class HomeViewPagerAdapter extends FragmentPagerAdapter {
    
        public static final int FRAGMENT_A_INDEX = 0;
        public static final int FRAGMENT_B_INDEX = 1;
        public static final int FRAGMENT_C_INDEX = 2;
    
        public static final int FRAGMENTS_COUNT = 3;
    
        public HomeViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case FRAGMENT_A_INDEX:
                    return FragmentA.newInstance();
                case FRAGMENT_B_INDEX:
                    return FragmentB.newInstance();
                case FRAGMENT_C_INDEX:
                    return FragmentC.newInstance();
                default:
                    return null;
            }
        }
    
        @Override
        public int getCount() {
            return FRAGMENTS_COUNT;
        }
    }
    

    and then link the adapter with the ViewPager in the hosting appcompat activity as here :

    HomeViewPagerAdapter homeTabsAdapter = new HomeViewPagerAdapter(getSupportFragmentManager());
    homeTabsViewPager.setAdapter(homeTabsAdapter);
    

    and you can easily switch between fragments by calling :

    homeTabsViewPager.setCurrentItem(HomeViewPagerAdapter.FRAGMENT_A_INDEX, false);