Switch Fragments while Maintaining State

耗尽温柔 提交于 2019-12-22 13:47:43

问题


Decided to rewrite this question:

I have three fragments call them A B C. Each has a view with some fields for the user to fill out. The user should be able to use a menu to switch between the different fragments. If the user fill outs information in fragment A and then switch to C fills out more information and then switches back to A the information the user typed in A should still be there.

I think I need to be using the FragmentManager somehow but I can't figure out the right combination of adds/ replaces / attaches ... that are required to make it work the way I want.

Can someone please provide a code snippet that would allow me to switch between fragments while maintaining each fragments view state.

Current Working Solution:

mContent is the active fragment and is a private member variable of the activity.

If anyone sees something wrong with this approach or a way to make it more efficient / more robust please let me know!

public void switchContent(String fragmentTag) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();

    if ( fragmentManager.findFragmentByTag( fragmentTag ) != mContent ) {
        if ( !mContent.isDetached() ) {
            transaction.detach( mContent );
        }

        if ( fragmentManager.findFragmentByTag( fragmentTag ) == null ) {
            if ( fragmentTag.equals( "details" ) ) {
                mContent = ScheduleDetailsFragment.newInstance();
            } else if ( fragmentTag.equals( "notes" ) ) {
                mContent = ScheduleNotesFragment.newInstance();
            } else if ( fragmentTag.equals( "exceptions" ) ) {
                // @TODO - Create Exceptions Fragment
            }
        } else {
            mContent = ( SherlockFragment ) fragmentManager.findFragmentByTag( fragmentTag );
        }
        if ( mContent.isDetached() ) {
            transaction.attach( mContent );
        } else if ( !mContent.isAdded() ) {
            transaction.add( R.id.content_frame, mContent, fragmentTag );
        }

        transaction.commit();
    }
    getSlidingMenu().showContent();
}

Thank You, Nathan


回答1:


I based my code of one of the examples provided but it returns a new fragment everytime a menu item is clicked so state information is lost.

If your pages hold onto some form of state/session, returning a new Fragment for every navigation event is a very poor user experience, and also not so good on memory usage.

I'd recommend having your sliding menu use the FragmentManager in your main Activity to maintain all of your Fragments that you switch between. It will manage all of their states, and you can retrieve them using findFragmentByTag(String tag). You would just need to ensure that each Fragment saves any state (values/data that changes after initial creation) that you add in onSaveInstanceState(Bundle outState) and restores it in onCreate(Bundle savedInstanceState). I'm not sure how the sliding menu you are using manages that currently, so this may not be possible. Hope this helps at least get you going in the right direction.

Edit: Updated answer for updated question - Here is how I would switch the Fragments. By using replace, you will completely switch the Fragments, while reusing the already created ones. In order for your Fragments to saved/restore their state, you need to refer to my answer above. If that is unclear, search for some examples of how to save state in Fragments and Activities.

public void switchContent(String fragmentTag) {

    // If our current fragment is null, or the new fragment is different, we need to change our current fragment
    if (mContent == null || !mContent.getTag().equals(fragmentTag)) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        // Try to find the fragment we are switching to
        Fragment fragment = fragmentManager.findFragmentByTag(fragmentTag);

        // If the new fragment can't be found in the manager, create a new one
        if (fragment == null) {
            if (fragmentTag.equals("details")) {
                mContent = ScheduleDetailsFragment.newInstance();
            }
            else if (fragmentTag.equals("notes")) {
                mContent = ScheduleNotesFragment.newInstance();
            }
            else if (fragmentTag.equals("exceptions")) {
                // @TODO - Create Exceptions Fragment
            }
        }
        // Otherwise, we found our fragment in the manager, so we will reuse it
        else {
            mContent = (SherlockFragment) fragment;
        }

        // Replace our current fragment with the one we are changing to
        transaction.replace(R.id.content_frame, mContent, fragmentTag);
        transaction.commit();

        getSlidingMenu().showContent();
    }
    else {
        // Do nothing since we are already on the fragment being changed to
    }
}


来源:https://stackoverflow.com/questions/14752895/switch-fragments-while-maintaining-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!