Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ChildFragmentManager java.lang.IllegalStateException: Activity has been destroyed

I have tried to add a fragment inside another fragment inside viewpager using getChildFragmentManager(). I got following error,

java.lang.IllegalStateException: Activity has been destroyed at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1549) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:654) at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:625) at com.lakeba.gameon.userprofile.UserProfileContainerFragment.replaceFragment(UserProfileContainerFragment.java:72)

And I tried this workaround but still getting same error.

UserProfileContainerFragment.java

public class UserProfileContainerFragment extends CustomFragment {


    private View rootView;
    private Fragment fragment1;

    public UserProfileContainerFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public static UserProfileContainerFragment newInstance() {
        UserProfileContainerFragment fragment = new UserProfileContainerFragment();
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.fragment_user_profile_container, container, false);

        if(savedInstanceState == null) {
            UserProfileFragment userProfileFragment = UserProfileFragment.newInstance();
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.user_profile_container, userProfileFragment)
                    .commitAllowingStateLoss();
        }

        return rootView;
    }

    /*@Override
    public void onSaveInstanceState(Bundle outState) {
        //super.onSaveInstanceState(outState);
    }*/

    public void replaceFragment(Fragment fragment, boolean addToBackStack){
        fragment1 = fragment;
        if(addToBackStack){
            /*getChildFragmentManager().beginTransaction()
                    .replace(R.id.user_profile_container, fragment)
                    .addToBackStack(null)
                    .commit();*/
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.user_profile_container, fragment)
                    .addToBackStack(null)
                    .commit();
                    //.commitAllowingStateLoss();
        }
        else{
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.user_profile_container, fragment)
                    .commit();
                    //.commitAllowingStateLoss();
        }

    }

    @Override
    public void onDetach() {
        super.onDetach();

        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }
}

HomeMapActivity.java

public class HomeMapActivity extends AppCompatActivity implements UserProfileFragment.OnUserProfileFragmentListener{

    private Toolbar homeToolbar;
    private ViewPager homeViewPager;
    private TabLayout homeTabLayout;
    private UserProfileContainerFragment userProfileContainerFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home_map);

        /*homeToolbar = (Toolbar) findViewById(R.id.home_toolbar);
        setSupportActionBar(homeToolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);*/

        homeViewPager = (ViewPager) findViewById(R.id.home_view_pager);

        HomeViewPagerAdapter homeViewPagerAdapter = new HomeViewPagerAdapter(getSupportFragmentManager());
        userProfileContainerFragment = new UserProfileContainerFragment();
        homeViewPagerAdapter.addFragment(new UserProfileContainerFragment(),"Profile");
        homeViewPager.setAdapter(homeViewPagerAdapter);

        homeTabLayout = (TabLayout) findViewById(R.id.home_tabs);
        homeTabLayout.setupWithViewPager(homeViewPager);
        setTabIcons(homeTabLayout);


        homeTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int tabPosition = tab.getPosition();
                tab.setIcon(tabIconsArrayActivated[tabPosition]);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                int tabPosition = tab.getPosition();
                tab.setIcon(tabIconsArray[tabPosition]);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                int tabPosition = tab.getPosition();
                tab.setIcon(tabIconsArrayActivated[tabPosition]);
            }
        });

        homeTabLayout.getTabAt(1).select();
    }

    private void setTabIcons(TabLayout homeTabLayout) {
        homeTabLayout.getTabAt(0).setIcon(tabIconsArray[0]);
        homeTabLayout.getTabAt(1).setIcon(tabIconsArray[1]);
        homeTabLayout.getTabAt(2).setIcon(tabIconsArray[2]);
        homeTabLayout.getTabAt(3).setIcon(tabIconsArray[3]);
    }

    @Override
    public void onUserProfileEditButtonClicked() {
        userProfileContainerFragment.replaceFragment(EditUserProfileFragment.newInstance(),true);
    }

    private class HomeViewPagerAdapter extends FragmentStatePagerAdapter{

        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public HomeViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            //return mFragmentTitleList.get(position);
            return null;
        }

        public void addFragment(Fragment fragment,String title){
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }
    }
}
like image 512
Ramprasad Avatar asked Jul 28 '16 06:07

Ramprasad


1 Answers

If you look at the code in your onCreate() method you'll see the lines:

userProfileContainerFragment = new UserProfileContainerFragment();
homeViewPagerAdapter.addFragment(new UserProfileContainerFragment(),"Profile");

You first initialize the userprofileContainerFragment field with a new instance of UserProfileContainerFragment and then right below you create a new instance of UserProfileContainerFragment to be used in the ViewPager(you can easily observe this by placing a log statement in the constructor of UserProfileContainerFragment...you'll see two instances being created). Later in your code you try to use the field userProfileContainerFragment which will lead to a failure as that instance of UserProfileContainerFragment is not attached to the activity at all(this isn't the fragment used by the ViewPager).

Your code should look like below, to maintain the proper reference and not create detached fragments:

userProfileContainerFragment = new UserProfileContainerFragment();
homeViewPagerAdapter.addFragment(userProfileContainerFragment,"Profile");
like image 90
user Avatar answered Nov 12 '22 09:11

user