Devin Rodriguez
Devin Rodriguez

Reputation: 1164

Losing fragment on rotation

I'm having a problem in my app where, even with some of the most basic code (see below), I'm losing a fragment view on rotation.

Everything starts off great:

Starting in portrait

Until you rotate:

Rotated to landscape

The story is the same the the other way as well:

Starting in landscape

Rotated to portrait

I'm not sure what is going on. I've tried to follow various tutorials and code examples, checked via logging to make sure that the fragments are being saved and restored, but to no avail. What am I doing wrong?

MainActivity.java

public class MainActivity extends FragmentActivity
{
    private FragmentManager fragment_manager;
    private CharacterMenuFragment characterMenuFragment;
    private CharacterEditFragment characterEditFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_frame);

        fragment_manager = getSupportFragmentManager();

        if (savedInstanceState != null) {
            characterMenuFragment = (CharacterMenuFragment) fragment_manager.getFragment(savedInstanceState, "characterMenuFragment");
            characterEditFragment = (CharacterEditFragment) fragment_manager.getFragment(savedInstanceState, "characterEditFragment");
        }

        if (characterMenuFragment == null) {
            Log.i("characterMenuFragment", "making new fragment");
            characterMenuFragment = new CharacterMenuFragment();
        } else {
            Log.i("characterMenuFragment", "re-using old fragment");
        }

        if (characterEditFragment == null) {
            Log.i("characterEditFragment", "making new fragment");
            characterEditFragment = new CharacterEditFragment();
        } else {
            Log.i("characterEditFragment", "re-using old fragment");
        }

        fragment_manager.beginTransaction().replace(R.id.menu_frame, characterMenuFragment).commit();
        fragment_manager.beginTransaction().replace(R.id.content_frame, characterEditFragment).commit();
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);

        fragment_manager.putFragment(savedInstanceState, "characterMenuFragment", characterMenuFragment);
        fragment_manager.putFragment(savedInstanceState, "characterEditFragment", characterEditFragment);
    }
}

CharacterEditFragment.java

public class CharacterEditFragment extends Fragment {

    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.hello_world, container, false);
        return view;
    }

}

CharacterMenuFragment.java

public class CharacterMenuFragment extends Fragment {

    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.hello_world, container, false);
        return view;
    }

}

content_frame.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <FrameLayout
        android:id="@+id/menu_frame"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />

</LinearLayout>

hello_world.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

Upvotes: 2

Views: 914

Answers (1)

Yet Another User Name
Yet Another User Name

Reputation: 76

Try this:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.content_frame);

    fragment_manager = getSupportFragmentManager();

    if (savedInstanceState != null) {
        characterMenuFragment = (CharacterMenuFragment) fragment_manager.getFragment(savedInstanceState, "characterMenuFragment");
        characterEditFragment = (CharacterEditFragment) fragment_manager.getFragment(savedInstanceState, "characterEditFragment");
    }

    if (characterMenuFragment == null) {
        Log.i("characterMenuFragment", "making new fragment");
        characterMenuFragment = new CharacterMenuFragment();
        fragment_manager.beginTransaction().replace(R.id.menu_frame, characterMenuFragment).commit();
    } else {
        Log.i("characterMenuFragment", "re-using old fragment");
    }

    if (characterEditFragment == null) {
        Log.i("characterEditFragment", "making new fragment");
        characterEditFragment = new CharacterEditFragment();
        fragment_manager.beginTransaction().replace(R.id.content_frame, characterEditFragment).commit();
    } else {
        Log.i("characterEditFragment", "re-using old fragment");
    }
}

Move the fragment managers into the applicable if statements above. You're just making sure to reuse the existing fragment and only creating one if the fragment doesn't exist.

Upvotes: 1

Related Questions