3

I'm developing an app which supports only two orientations, portrait and reverse portrait, so I wrote "sensorPortrait" in my manifest, and it works well.

The problem is, I want to use different layouts for these two orientations.

Enabling sensorPortrait disables the "onConfigurationChange" call.

I use:

orientationEventListener = new OrientationEventListener(this) {
        @Override
        public void onOrientationChanged(int i) {
            int newOrientation = getScreenOrientation();
            if (newOrientation != orientation) {
                orientation = newOrientation;
                if (newOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
                    ...
                    setContentView(R.layout.main);

                } else if (newOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
                    ...
                    setContentView(R.layout.main_reverse_portrait);
                }
            }
        }
    };
    orientationEventListener.enable();

The problem is that this code is being called AFTER changing orientation, so when the user rotates the phone at first they see the previous layout, rotated automatically by Android, and then the correct layout. It looks unacceptable, do you know how to fix it?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
leshka
  • 1,764
  • 6
  • 32
  • 42

3 Answers3

9

I recommend you use the configChanges and override the onConfigurationChanged(Configuration newConfig) method. Ignore the orientation if it is not the one you support.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
         ...
         setContentView(R.layout.main);
    } else if (newOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
         ...
         setContentView(R.layout.main_reverse_portrait);
    }
}

This answer might further help you.

Android: Detect Orientation Changed

Update:

There is a method getChangingConfigurations() that you can use in onStop() to determine what configuration change is causing the activity to be destroyed. In this case you don't need to use the onConfigurationChanged() callback.

Update 2:

Use sensorPortrait and check rotation angle manually in onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    Display display = ((WindowManager)  
          context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int rotation = display.getRotation();
    if (rotation == Surface.ROTATION_180) { // reverse portrait
       setContentView(R.layout.main_reverse_portrait);
    } else {  // for all other orientations
       setContentView(R.layout.main);
    }
    ...
}
Community
  • 1
  • 1
Ron
  • 24,175
  • 8
  • 56
  • 97
  • I just want to add that in almost all cases you will want to support all orientations. When an user rotates the device and nothing happens, it is always frustrating. There are legitimate cases when you want to force an orientation, but 99% of the time, you should support all orientations. – Teovald Sep 19 '12 at 11:29
  • sometimes it's up to customer=( Of course it was not my own decision – leshka Sep 19 '12 at 12:44
  • maybe I don't understand the idea of the orientation. But I thought that if you enable all the orientations than screen coordinates will rotate. I mean that android will use a portrait layout for landscape and it will look bad. no? What do you mean by ignoring other orientations? any code would be appreciated. I have two layout files for portrait and reverse-portrait. – leshka Sep 19 '12 at 12:47
  • this answer will help you.. http://stackoverflow.com/questions/8248274/android-detect-orientation-changed – Ron Sep 19 '12 at 13:58
  • Check this API http://developer.android.com/reference/android/app/Activity.html#getChangingConfigurations() – Ron Sep 19 '12 at 14:33
  • upd: sorry for long delay but.. The problem is that if I don't call to super.onConfigurationChange() I get runtime error: ERROR/AndroidRuntime(7868): FATAL EXCEPTION: main android.app.SuperNotCalledException: Activity Orientation did not call through to super.onConfigurationChanged() – leshka Sep 25 '12 at 15:00
  • and if I do then Orientation changes to landscape anyway – leshka Sep 25 '12 at 15:00
  • How did it go with using getChangingConfigurations() – Ron Sep 25 '12 at 15:23
  • actually i don't want my activity to be restarted so if your original answer works - I want to use it=) 5 people think that you are correct - it means something=) But I don't understand what should I do with calling super method - may be it's an android version issue? For me it's possible that this thing will work only for android 4, but for android 2.3 it should not crash.. – leshka Sep 25 '12 at 17:42
  • Its not an android version issue.. I have updated the answer with another option, doesn't match 100% to your requirement, but will fix the issue.(activity must be restarted) – Ron Sep 25 '12 at 18:26
0

if u debug u would notice onConfigurationChanged gets called twice for few of the configurations(i think it used to call twice while going to landscape mode). So ur problem is there. As onConfigurationChanged will call setContent twice. U should avoid this either by comparing the current display width with the old width or something similar. Do let me know if this doesnt works, il try on my own then :) gl!

con_9
  • 2,491
  • 3
  • 23
  • 31
  • If I rotate device quickly - than no, it calls the method only once, but if I slowly rotate - than yes, twice. But I don't see any problem with this because my method always uses the correct layout (neither does android automatically) – leshka Sep 25 '12 at 15:16
  • upd. previous was wrong... I've noticed that when I rotate device quickly - then it doesn't call the method! I guess it covers only portrait->landscape and vise versa configuration changes. I guess this won't help me=(.. – leshka Sep 25 '12 at 17:19
0

You can try writing code to make layout invisible to a notification for user in onPause of the app.

That might help to make things bit better

Calvin
  • 617
  • 1
  • 12
  • 34