Question

I have an activity that has four fragments on it in the form of:

 -----------  
|  1  |  2  |
 -----------
|     3     |
 -----------
|     4     |
 -----------

When I rotate the screen the fragments should look like this:

 -----------
|   | 2 |   |
| 1 |---| 4 |
|   | 3 |   |
 -----------

I have the layout files created properly for landscape vs portrait etc and if I start the app in either orientation it works fine. However, when I rotate the app, I lose some fragments. For example, if I start in portrait mode and rotate to landscape mode, fragments 2 and 3 are now blank and don't show up, and if I rotate back to portrait mode, the app crashes because it can no longer find those fragments to add back to the app.
Here's my code in my onCreate and my XML files. Any help is greatly appreciated!

Main.java

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

    if (savedInstanceState == null) {
        ssf = new StartStopFragment();
        tkf = new TimeKeeperFragment();
        rf = new ResetFragment();
        lcf = new LapCounterFragment();
    } else {
        ssf = (StartStopFragment) getFragmentManager().findFragmentByTag(StartStopFragment.class.getName());
        tkf = (TimeKeeperFragment) getFragmentManager().findFragmentByTag(TimeKeeperFragment.class.getName());
        rf = (ResetFragment) getFragmentManager().findFragmentByTag(ResetFragment.class.getName());
        lcf = (LapCounterFragment) getFragmentManager().findFragmentByTag(LapCounterFragment.class.getName());
    }

    getFragmentManager().beginTransaction()
            .replace(R.id.flStartFrame, ssf, StartStopFragment.class.getName())
            .replace(R.id.flTimeKeeperFrame, tkf, TimeKeeperFragment.class.getName())
            .replace(R.id.flResetFrame, rf, ResetFragment.class.getName())
            .replace(R.id.flLapCounterFrame, lcf, LapCounterFragment.class.getName())
            .commit();
}

layout\main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false">
    <LinearLayout
        android:id="@+id/llTopContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".4"
        android:orientation="horizontal"
        android:baselineAligned="false">
        <FrameLayout
            android:id="@+id/flResetFrame"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".5"
            tools:layout="@layout/fragment_reset"/>
        <FrameLayout
            android:id="@+id/flLapCounterFrame"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".5"
            tools:layout="@layout/fragment_lapcount"/>
    </LinearLayout>
    <FrameLayout
        android:id="@+id/flTimeKeeperFrame"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".2"
        tools:layout="@layout/fragment_time"/>
    <FrameLayout
        android:id="@+id/flStartFrame"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".4"
        tools:layout="@layout/fragment_startstop"/>
</LinearLayout>

layout-land\main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false">
    <LinearLayout
        android:id="@+id/llTopContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".4"
        android:orientation="horizontal"
        android:baselineAligned="false">
        <FrameLayout
            android:id="@+id/flResetFrame"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".5"
            tools:layout="@layout/fragment_reset"/>
        <FrameLayout
            android:id="@+id/flLapCounterFrame"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".5"
            tools:layout="@layout/fragment_lapcount"/>
    </LinearLayout>
    <FrameLayout
        android:id="@+id/flTimeKeeperFrame"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".2"
        tools:layout="@layout/fragment_time"/>
    <FrameLayout
        android:id="@+id/flStartFrame"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".4"
        tools:layout="@layout/fragment_startstop"/>
</LinearLayout>
Was it helpful?

Solution

Don't replace the fragment on orientation change. Just check if saved instance is null, and add the fragment and commit .

When Activity recreate on orientation change, the Fragment Manager will keep hold of the fragment instance and onCreateView will be called.

Hope this works. Let me know .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top