简体   繁体   中英

Removing a fragment and then re-adding it

I've written a method, setLoading in my activity that is responsible for setting the "loading" status of my app. This method is responsible for instantiating a LoadingFragment , removing any existing instances of it (Using FragmentManager ) and then depending on it's first parameter loading , adding it to one of two possible containers (Depending on the top parameter).

protected LoadingFragment loadingFragment;

public void setLoading(boolean loading, boolean top) {
    FragmentManager fragmentManager = getFragmentManager();

    // Create LoadingFragment instance if it has not already been created
    if (loadingFragment == null || !(loadingFragment instanceof LoadingFragment)) {
        loadingFragment = new LoadingFragment();
    }

    // Remove the fragment first if it is present
    fragmentManager
            .beginTransaction()
            .remove(loadingFragment)
            .commit();

    // Only if loading is true should we display the fragment
    if (loading) {
        // Decide which container we're going to put the fragment in
        int id = top ? R.id.topContainer : R.id.container;

        // Place the fragment in the right position
        fragmentManager
                .beginTransaction()
                .add(id, loadingFragment)
                .commit();
    }
}

public void setLoading(boolean loading) {
    setLoading(loading, true);
}

I am triggering setLoading(true) from elsewhere in my activity and I have commented out it's corresponding setLoading(false) while testing.

What I want to happen is for my LoadingFragment to appear every time setLoading(true) is called. The first call shouldn't remove anything since it at that point it doesn't exist. All subsequent calls should remove the existing LoadingFragment and add it again.

What happens is that the first call to setLoading(true) does indeed create the LoadingFragment and put it in the correct container. However, subsequent calls to setLoading(true) remove the fragment, but it never seems to be re-added. I have checked to see that the fragment does indeed exist and is of type LoadingFragment at the point it is added and I have also checked to ensure that it's onCreateView method is being called.

Am I doing something wrong?

Edit

Using the answer given below by H Raval as a base I have now come up with the following:

public void setLoading(boolean loading, boolean top) {
    FragmentManager fragmentManager = getFragmentManager();

    Fragment currentLoadingFragment = fragmentManager.findFragmentById(R.id.loadingFragment);
    if (currentLoadingFragment != null) {
        fragmentManager
                .beginTransaction()
                .remove(currentLoadingFragment)
                .commit();
    }

    if (loading) {
        int id = top ? R.id.topContainer : R.id.container;

        fragmentManager
                .beginTransaction()
                .add(id, new LoadingFragment())
                .commit();
    }
}

This seems to work as expected. It seems that the primary difference is that this code is creating a new LoadingFragment instance each time (When loading = true ) whereas originally I was trying to use the same instance and just adding/removing it using the FragmentManager .

Out of interest, is there a reason I need to create a new instance after using remove ? Is this the correct way to do it? Or should it still work when using the same instance? Additionally, if it's recommended to create a new instance each time, is there anything I should do in terms of clean-up, freeing up resources etc. (Perhaps there's a way of gracefully destroying the obsolete instances)?

well i have made some changes in your code and works perfect for me..let me know if you face any difficulty

public void loadFragment(boolean loading, boolean top){
        FragmentManager fragmentManager = getSupportFragmentManager();

          loadingFragment = new LoadingFragment();

        // Only if loading is true should we display the fragment
        if (loading) {
            // Decide which container we're going to put the fragment in
            int id = top ? R.id.topContainer : R.id.container;

            if(top){
                if(fragmentManager.findFragmentByTag("loadingFragment")!=null)
                    fragmentManager.beginTransaction().remove(fragmentManager.findFragmentByTag("loadingFragment")).commit();

                fragmentManager
                        .beginTransaction()
                        .replace(R.id.topContainer, loadingFragment,"toploadingFragment")
                        .commit();
            }else{
                if(fragmentManager.findFragmentByTag("toploadingFragment")!=null)
                    fragmentManager.beginTransaction().remove(fragmentManager.findFragmentByTag("toploadingFragment")).commit();

                fragmentManager
                        .beginTransaction()
                        .replace(R.id.container, loadingFragment,"loadingFragment")
                        .commit();
            }

        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM