0

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

Community
  • 1
  • 1
Russ Wheeler
  • 2,590
  • 5
  • 30
  • 57
  • What folder did you put your landscape layout file in? – Parnit May 12 '14 at 17:55
  • I have two files, one in normal layout and the other in layout-land. The layout-land file is being used because the phone is being held in landscape, even though the activity is locked to portrait. – Russ Wheeler May 13 '14 at 07:37
  • Please have a look at [this](https://stackoverflow.com/questions/9627774/android-allow-portrait-and-landscape-for-tablets-but-force-portrait-on-phone/60728531#60728531) answer hope this helps someone – Rahul Mar 17 '20 at 18:49

2 Answers2

2

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).

I'm pretty sure this is the root of your problem. You should be able to accomplish what you are trying to do without overriding onConfigurationChanged. Let the OS handle the configuration changes and provide the correct layout files.

If you do this, you should be good on Tablets. They should not set a particular orientation and they should open to the correct orientation for each Activity. The phone devices will have that issue you are talking about with the quick black screen. What is happening is that the Activity will open first in the orientation the phone is held in, say Landscape. Then it will set its orientation to Portrait in code and undergo a configuration change, recreating the Activity and causing the momentary flash you are seeing.

There are ways you can mitigate this.

  • Use android:screenOrientation="behind" in the AndroidManifest.xml for each Activity. This will start the Activity in the orientation that the previous Activity was in (Portrait for phones, whatever for tablets). Then you never have to worry about the Activity getting created twice because it will always start itself in the correct orientation.

  • This does not fix your very first Activity however. You can either deal with the launcher Activity having that flash exactly once when the app launches, or you can set the launcher Activity to android:screenOrientation="portrait" in the manifest and make sure to set tablets to setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); in code. This may cause that flash to occur on startup for Tablets.

Using just the first bullet point should be good enough, but you should tailor your implementation to your app's user experience requirements.

jacobhyphenated
  • 2,105
  • 2
  • 17
  • 27
  • This all sounds good, but I don't think it will save the overriding problem I have of the landscape layout file being used when the phone is held in landscape, even if I set the orientation to portrait with setRequestedOrientation. I realised that as I only want landscape in tablets that to move the landscape layout and value files out of standard landscape folders and into sw600dp folders solved all my issues. – Russ Wheeler May 14 '14 at 14:49
  • @RussWheeler If you are not manually handling configuration changes, the OS will provide the correct resource. If your devices orientation is set to portrait, you should get the portrait layout regardless of how you are holding the device. That is why I suggested that the `onConfigurationChange` code was the root of your problem. – jacobhyphenated May 14 '14 at 17:20
  • OK I'll try that out tmrw – Russ Wheeler May 15 '14 at 23:28
2

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.

Parnit
  • 1,032
  • 2
  • 8
  • 16
  • Thanks, this is what I actually realised about 3 hours before you replied, so I did that. It didn't answer my original problem, that you don't get the resource files according to the newly set orientation, but to that that the phone is in. But your answer is what I did to solve my problem so I'll give you the tick – Russ Wheeler May 14 '14 at 14:57