Search code examples
androidandroid-layoutonconfigurationchanged

Android - Lock phone to portrait but allow tablet to be both landscape and portrait


I am trying to write an app where I want the phone to be locked to portrait, but allow the tablet version to have both landscape and portrait.

I have created something that almost works based on all the following questions...

How do I lock screen orientation for phone, but not for tablet? (Android) How to allow both landscape/portrait for tablets only Portrait for phone, landscape for Tablet (Android-Layout) landscape mode in tablet only Locking phone in portrait mode

What I've done so far is extend Activity into my own base Activity and to include orientation change code in both onCreate and an overwritten onConfigurationChanged

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if(!(new DeviceHelper().isTablet(this)))
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        super.onCreate(savedInstanceState);
        setupActionBar(getActivity());


    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        //don't reload the current page when the orientation is changed
        if(!(new DeviceHelper().isTablet(this)))
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        super.onConfigurationChanged(newConfig);

    }

Everything with this works fine (I overwrote the onConfigurationChanged to avoid the activity being destroyed and recreated which lead to a black screen for a fraction of a second).

My main problem is that if you hold the phone in landscape, then the activity remains in portrait...perfect! However, because the phone is in actual landscape then the layout for landscape is used, which is a layout from the tablet.

My understanding was that when setRequestedOrientation is called, then it should fire onConfigurationChanged instantly, however, the fragment is called first, then the layout inflated incorrectly, before then calling onConfigurationChanged, which means the landscape layout is already set.

I understand that I could possibly set the layout in each of my activities, based on the configuration but I don't really want to do that.

So how can I get the app to use the appropriate layout file from the appropriate res folder, based on the setRequestedOrientation.

Thanks


Solution

  • If your landscape layout is just for tablets, I would suggest you put it in the tablet layout folders ie: layout-sw600dp-land (for 7in tablet landscape) and layout-sw720dp-land (for 10in tablet landscape). This way, the tablet layout will only be used in tablets. If you do not declare a landscape layout for the phone, it will use the regular portrait layout. Separating layout folders for the tablet and phone layouts helps for organization.