Search code examples
androidlayoutscreen-orientationonconfigurationchanged

onConfigurationChanged Rearrange layout for orientation


I have an image viewer app that handles very large images with significant caching. When a user rotates the device it would cause a hiccup if the app fully restarts.

If I disable the orientation changes then device rotations are seamless, but I have a sidebar that is oriented differently in landscape and portrait. With orientation changes disabled the sidebar will stay in it's previous state eating up massive chunks of real estate.

Is there a way I could allow the layout aspects to update on a rotation without fully restarting the activity?


EDIT (More Info)


I'm adding more info to make my original question more clear so I can answer it. The layout is as such:

 ___ _
|   | |
| V |S|  Landscape
|___|_|

 ___
|   |
| V |
|___|   Portrait
|_S_|

V = Viewer S = Sidebar

The sidebar is the same fragment, however it uses a different layout based on the orientation. My original attempt was a complicated multi-layout setup. This worked fine when I allowed the activity to restart on orientation changes. However since I don't want to reissue all the heavy lifting (or add instance saving overhead) I needed to find a way to adjust the layout on orientation changes without a full restart.


Solution

  • What I ended up doing was adjusting the layout to handle both landscape and portrait with empty containers that would later be filled with the proper fragment:

    <RelativeLayout>
       ...
       <FrameLayout
           android:id="@+id/xmpRightContainer"
           android:layout_width="wrap_content"
           android:layout_height="match_parent"
           android:layout_alignParentRight="true"  >
       </FrameLayout>
    
       <FrameLayout
           android:id="@+id/xmpBottomContainer"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_alignParentBottom="true"  >
       </FrameLayout>
    </RelativeLayout>
    

    In onConfigurationChanged:

        if (xmpFrag != null)
        {
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.remove(getSupportFragmentManager().findFragmentByTag(XmpFragment.FRAGMENT_TAG));
            ft.commit();
            fm.executePendingTransactions();
        }
    
        xmpFrag = new XmpFragment();
        int container;
        boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
        if (isPortrait)
        {
            container = R.id.xmpBottomContainer;
        }
        else
        {
            container = R.id.xmpRightContainer;
        }
    
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(container, xmpFrag, XmpFragment.FRAGMENT_TAG);      
        ft.commit();
        fm.executePendingTransactions();
    

    This works perfectly and rotating the device is seamless to the user now.