how to handle view rotations like youtube do on android? - android

I want to achieve the way youtube handles its video orientation.
There are a few things to have in mind before just saying that I have to use onConfigurationChanged.
THINGS TO CONSIDER
The phone orientation. This means the way you hold de phone. It could be PORTRAIT or LANDSCAPE
The screen orientation. This means the way the view is displayed. It could be PORTRAIT or LANDSCAPE regardless of the orientation of the phone
HOW YOUTUBE ROTATION WORKS?
If the phone is in PORTRAIT mode (using OS quick settings)
The screen will keep in PORTRAIT. It doesn't matter if you rotate the phone
The only way to rotate de screen is by pressing the rotate button.
The screen will keep in the last orientation chooses, and it will not change even if you rotate the phone. PORTRAIT will remain PORTRAIT, and LANDSCAPE will remain LANDSCAPE.
If the phone is in AUTO-ROTATE mode
if you rotate the phone, then the screen rotation follows it. I mean, if the phone is in PORTRAIT, the screen will be PORTRAIT. And the same happens with LANDSCAPE.
if the rotate button is pressed, the screen orientation will change regardless of the phone orientation. In this case, the only way to listen to the sensor orientation is to rotate the phone to the same side of the screen rotation and go back. This is to let the phone sensor have control of the orientation again.
WHAT I HAVE?
With onConfigurationChanged I could know when I rotate the phone (if AUTO-ROTATE is enabled) and define the layout:
override fun onConfigurationChanged(newConfig: Configuration) {
when (newConfig.orientation) {
Configuration.ORIENTATION_PORTRAIT -> buildPortrait()
Configuration.ORIENTATION_LANDSCAPE -> buildLandscape()
}
super.onConfigurationChanged(newConfig)
}
With the rotation button, I can handle screen orientation (when the phone is in PORTRAIT BLOCKED from OS)
fun rotate() {
val orientation = requireActivity().requestedOrientation
val isRotationOn = Settings.System.getInt(requireActivity().contentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0) == 1
requireActivity().requestedOrientation = if (isRotationOn) {
// AUTO-ROTATE enabled
TODO()
} else
// PORTRAIT BLOCKED
if (orientation == PORTRAIT) {
buildLandscape()
LANDSCAPE
} else {
buildPortrait()
PORTRAIT
}
}
WHAT I CAN'T ACHIEVE?
I don't know how to handle screen rotation when I have the AUTO-ROTATE enabled that handles the rotation by the sensor, and at the same time, there is a rotate button that does a rotation regardless of the AUTO-ROTATE.
IMPORTANT: I can't find any example with the solution anywhere.

You need to use OrientationEventListener to listen to orientation change and set requestedOrientation back to ActivityInfo.SCREEN_ORIENTATION_USER when orientation changed.
The orientation value passed in onOrientationChanged is from 0 to 359 and -1 means flat. You need to map it into 4 directions according to the following code.
orientationEventListener = object: OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
val newOrientation = when (orientation) {
in 0 .. 44 -> 0
in 45 .. 134 -> 1
in 135 .. 224 -> 2
in 225 .. 314 -> 3
in 315 .. 359 -> 0
else -> ORIENTATION_UNKNOWN
}
if (newOrientation != previousOrientation) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER
}
previousOrientation = newOrientation
}
}
And remember to only enable the above listener if auto-rotate setting is on
val autoRotationOn = Settings.System.getInt(contentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0) == 1
if (autoRotationOn) {
orientationEventListener.enable()
} else {
orientationEventListener.disable()
}
As the auto-rotate setting could be changed within the lifecycle of current activity, you have to listen to the value change and enable/disable the orientationEventListener.
private val contentObserver = object:ContentObserver(handler) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
setupOrientationEventListener()
}
}
val settingUri = Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION)
contentResolver.registerContentObserver(settingUri, false, contentObserver)

Related

How to detect screen rotation without rotating/recreating the activity?

I want to be able to detect whether the phone is in landscape or portrait mode, but I don't want my activity and all my buttons to rotate along.
This code detects the rotation, but it also rotates the screen:
Display display = getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
rotVal.setText("Rotation: " + rotation);
I tried to lock the activity in portrait mode with this in the MainActivity, but then rotation value doesn't change. (Makes sense I guess)
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
I also tried android:screenOrientation="portrait" in the manifest file but the rotVal stays zero.
This answer have a rotating animation, and I don't want that. I want the screen to stay as it is even in landscape mode, no rotating, no animation, etc.
This answer doesn't work. When I rotate the phone, the rotVal stays zero.
Is there a way to detect the orientation without rotating/recreating the layout?
The second Stack Overflow answer you link to will work, but you can't inquire for the orientation like you do.
First, lock the app in portrait mode. The following code should work and does not include all the animation code.
private lateinit var orientationListener: OrientationListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Code here to do Activity-related stuff.
// Set up a listener to detect orientation changes.
orientationListener = OrientationListener(this)
}
override fun onStart() {
orientationListener.enable()
super.onStart()
}
override fun onStop() {
orientationListener.disable()
super.onStop()
}
private class OrientationListener(context: Context?) : OrientationEventListener(context) {
val ROTATION_O = 1 // portrait
val ROTATION_90 = 2 // landscape counter-clockwise
val ROTATION_180 = 3 // portrait inverted
val ROTATION_270 = 4 // landscape clockwise
private var rotation = 0
override fun onOrientationChanged(orientation: Int) {
if ((orientation < 35 || orientation > 325) && rotation != ROTATION_O) { // PORTRAIT
rotation = ROTATION_O
} else if (orientation > 145 && orientation < 215 && rotation != ROTATION_180) { // REVERSE PORTRAIT
rotation = ROTATION_180
} else if (orientation > 55 && orientation < 125 && rotation != ROTATION_270) { // REVERSE LANDSCAPE
rotation = ROTATION_270
} else if (orientation > 235 && orientation < 305 && rotation != ROTATION_90) { //LANDSCAPE
rotation = ROTATION_90
}
// We'll just display the value, but it should be stashed for further use or acted upon immediately.
Log.d("Applog", "rotation = $rotation")
}
}

How to determine correct device orientation in Android N multi-window mode?

From Multi-Window documentation:
Disabled features in multi-window mode
Certain features are disabled or ignored when a device is in multi-window mode, because they don’t make sense for an activity which may be sharing the device screen with other activities or apps. Such features include:
Some System UI customization options are disabled; for example, apps cannot hide the status bar if they are not running in full-screen mode.
The system ignores changes to the android:screenOrientation attribute.
I get that for most apps it doesn't make sense to distinct between portrait and landscape modes, however I am working on SDK which contains camera view which user can put on any activity they wish - including activity that supports multi-window mode. The problem is that camera view contains SurfaceView/TextureView which displays the camera preview and in order to display preview correctly in all activity orientations, knowledge about correct activity orientation is required so that camera preview can be correctly rotated.
The problem is that my code which calculates correct activity orientation by examining current configuration orientation (portrait or landscape) and current screen rotation. The problem is that in multi-window mode current configuration orientation does not reflect the real activity orientation. This then results with camera preview being rotated by 90 degrees because Android reports different configuration than orientation.
My current workaround is to check for requested activity orientation and use that as a basis, but there are two problems with that:
the requested activity orientation does not have to reflect actual activity orientation (i.e. request may still not be fulfilled)
the requested activity orientation can be 'behind', 'sensor', 'user', etc. which does not reveal any information about current activity orientation.
According to documentation, screen orientation is actually ignored in multi-window mode, so 1. and 2. just won't work
Is there any way to robustly calculate correct activity orientation even in multi-window configuration?
Here is my code that I currently use (see comments for problematic parts):
protected int calculateHostScreenOrientation() {
int hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
int rotation = getDisplayOrientation(wm);
boolean activityInPortrait;
if ( !isInMultiWindowMode() ) {
activityInPortrait = (mConfigurationOrientation == Configuration.ORIENTATION_PORTRAIT);
} else {
// in multi-window mode configuration orientation can be landscape even if activity is actually in portrait and vice versa
// Try determining from requested orientation (not entirely correct, because the requested orientation does not have to
// be the same as actual orientation (when they differ, this means that OS will soon rotate activity into requested orientation)
// Also not correct because, according to https://developer.android.com/guide/topics/ui/multi-window.html#running this orientation
// is actually ignored.
int requestedOrientation = getHostActivity().getRequestedOrientation();
if ( requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT ) {
activityInPortrait = true;
} else if ( requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE ||
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE ) {
activityInPortrait = false;
} else {
// what to do when requested orientation is 'behind', 'sensor', 'user', etc. ?!?
activityInPortrait = true; // just guess
}
}
if ( activityInPortrait ) {
Log.d(this, "Activity is in portrait");
if (rotation == Surface.ROTATION_0) {
Log.d(this, "Screen orientation is 0");
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (rotation == Surface.ROTATION_180) {
Log.d(this, "Screen orientation is 180");
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
} else if (rotation == Surface.ROTATION_270) {
Log.d(this, "Screen orientation is 270");
// natural display rotation is landscape (tablet)
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else {
Log.d(this, "Screen orientation is 90");
// natural display rotation is landscape (tablet)
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
} else {
Log.d(this, "Activity is in landscape");
if (rotation == Surface.ROTATION_90) {
Log.d(this, "Screen orientation is 90");
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (rotation == Surface.ROTATION_270) {
Log.d(this, "Screen orientation is 270");
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
} else if (rotation == Surface.ROTATION_0) {
Log.d(this, "Screen orientation is 0");
// natural display rotation is landscape (tablet)
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
Log.d(this, "Screen orientation is 180");
// natural display rotation is landscape (tablet)
hostScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
}
return hostScreenOrientation;
}
private int getDisplayOrientation(WindowManager wm) {
if (DeviceManager.getSdkVersion() < 8) {
return wm.getDefaultDisplay().getOrientation();
}
return wm.getDefaultDisplay().getRotation();
}
private boolean isInMultiWindowMode() {
return Build.VERSION.SDK_INT >= 24 && getHostActivity().isInMultiWindowMode();
}
protected Activity getHostActivity() {
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity) context;
}
context = ((ContextWrapper) context).getBaseContext();
}
return null;
}
EDIT: I've reported this also to Android issue tracker.
I don’t know if this should be considered a solution or just a workaround.
As you say, your problems come with Android N and its multi-window mode. When the app is in multi window, your Activity is not tied to the full display dimensions. This redefines the concept of Activity orientation. Quoting Ian Lake:
Turns out: “portrait” really just means the height is greater than the
width and “landscape” means the width is greater than the height. So
it certainly makes sense, with that definition in mind, that your app
could transition from one to the other while being resized.
So there is no link anymore between Activity orientation changing and device physically being rotated. (I think the only reasonable use of Activity orientation changes now is to update your resources.)
Since you are interested in device dimensions, just get its DisplayMetrics. Quoting docs,
If requested from non-Activity context
metrics will report the size of the entire display based on current
rotation and with subtracted system decoration areas.
So the solution is:
final Context app = context.getApplicationContext();
WindowManager manager = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
boolean portrait = height >= width;
Width and height values will be swapped (more or less) when the device is tilted.
If this works, I would personally run it every time, deleting the isInMultiWindowMode() branch, because
it’s not expensive
our assumptions stand also in the non-multi-window mode
it will presumably work well with any other future kinds of modes
you avoid the race condition of isInMultiWindowMode() described by CommonsWare
I thought you could utilise the accelerometer to detect where's "down" - and thus the orientation of the phone. The Engineer Guy explains that that's the way the phone itself does it.
I searched here on SO for a way to do that and found this answer. Basically you need to check which of the 3 accelerometers detect the most significant component of the gravitational pull, which you know is roughly 9.8m/s² near the ground of the earth. Here's the code snippet from it:
private boolean isLandscape;
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER),1000000);
private final SensorEventListener mSensorListener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent mSensorEvent) {
float X_Axis = mSensorEvent.values[0];
float Y_Axis = mSensorEvent.values[1];
if((X_Axis <= 6 && X_Axis >= -6) && Y_Axis > 5){
isLandscape = false;
}
else if(X_Axis >= 6 || X_Axis <= -6){
isLandscape = true;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Be careful as this code might not work in every situation, as you need to take into account scenarios like being on a stopping/accelerating train or moving the phone fast in a game - here's the orders of magnitude page on wiki to get you started. It looks like you're safe with the values Khalil put in his code (in his answer), but I would take extra caution and research into what values might be generated in the different scenarios.
It's not a flawless idea, but I think as long as the API is built the way it is - whithout allowing you to get their calculated orientation - I think it's a beneficial workaround.

Different screen orientation on different devices when landscape mode

I am using
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
for my Activity and I am trying to use OrientationEventListener to find the orientation of the device. On some devices my landscape orientation is showing values around 270 and other devices shows values around 0. On every device where the Home button is placed the orientation value shows 0. I want to have same values when holding the all devices in landscape mode. Is there a flag that can show me which device is showing 270 or 0 for landscape mode as default orientation.
This is my OrientationEventListener
mOrientationListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
#Override
public void onOrientationChanged(int orientation) {
Log.v("Orientation changed to ", String.valueOf(orientation));
}
};
Is there a trick that can help to resolve the issue?
I have found the solution.
With this code I am getting the default display rotation:
int rotation = getWindowManager().getDefaultDisplay().getRotation();
in the body of my onOrientationChanged method I can make this:
if (rotation == 0) {
if (orientation >= 90 && orientation <= 270) {
}
} else if (rotation == 1) {
if (orientation < 180 && orientation > 0 ) {
}
}
This will enter the if only if my device is not in the correct landscape position. If my device is on 90+ angle I can give the user a message.

Toggling fullscreen & orientation like YouTube

I am trying to mimic the behavior of the YouTube Android app when the "fullscreen" button is clicked in the video player:
If device is currently in portrait, immediately rotate to landscape (even if user is still holding the device in portrait) and remain in landscape until user rotates device to landscape and then rotates back to portrait
If device is currently in landscape, immediately rotate to portrait (Even if user is still holding the device in portrait) and remain in portrait until the user rotates the device to portrait and then rotates back to landscape.
At anytime, allow the user to manually rotate their device to the desired orientation.
It seems that if I force the rotation to landscape or portrait using:
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
or
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
... I immediately lose the ability to detect sensor orientation changes (i.e. once the user is in landscape, and they want to manually rotate the device back to portrait).
If I change the requested orientation to unspecified or sensor in onConfigurationChanged, the orientation briefly flips to landscape/portrait (whatever I requested from above) and then snaps back to the orientation that matches how the device is held.
Any thoughts on how to achieve my goals above?
I had the excact same problem. What I ended up with was using an OrientationListener to detect when the user had actually tilted the phone to landscape and then setting the orientation to SCREEN_ORIENTATION_SENSOR.
OrientationEventListener orientationEventListener =
new OrientationEventListener(getActivity()) {
#Override
public void onOrientationChanged(int orientation) {
int epsilon = 10;
int leftLandscape = 90;
int rightLandscape = 270;
if(epsilonCheck(orientation, leftLandscape, epsilon) ||
epsilonCheck(orientation, rightLandscape, epsilon)){
getMainActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
}
private boolean epsilonCheck(int a, int b, int epsilon) {
return a > b - epsilon && a < b + epsilon;
}
};
orientationEventListener.enable();
Here is the documentation for OrientationEventListener : Documentation
You would also need to add checks for portrait , because you described needing that in your original post.
Big tnx to havch
It is gold, I was stuck on that for 5 hours. Here is my kotlin piece of code to deal with it.
orientationEventListener = object: OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
val isPortrait = orientation > 300 || orientation < 60 || orientation in 120..240
if ((requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT && isPortrait) ||
(requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && !isPortrait)){
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
}
}
}
orientationEventListener.enable()
This modification of Alexander code is working better for me
object : OrientationEventListener(requireContext()) {
override fun onOrientationChanged(orientation: Int) {
val isPortrait = orientation > 345 || orientation < 15 || orientation in 165..195
val isLandscape = orientation in 255..285 || orientation in 75..105
if (
(requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT && isPortrait) ||
(requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && isLandscape)
) {
lifecycleScope.launch {
// adding a delay to avoid orientation change glitch
delay(200)
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
}
}
}
}
/**
* -1 -> Unknown
* 1 -> Portrait
* 0 -> Landscape
*/
var previousOrientation = -1
val orientationEventListener: OrientationEventListener =
object : OrientationEventListener(this) {
override fun onOrientationChanged(orientation: Int) {
val isPortrait = (orientation > 340 || orientation < 20 || orientation in 160..200) &&
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
val isLandscape = (orientation in 250..290 || orientation in 70..110) &&
requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
if (isPortrait || isLandscape) {
lifecycleScope.launch {
if (previousOrientation == -1) {
previousOrientation = if (isPortrait) 1 else 0
}
delay(700)
val currentOrientation = if (isPortrait) 1 else 0
if (previousOrientation == currentOrientation) {
previousOrientation = -1
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
}
}
}
}
}
orientationEventListener.enable()
This one handles the orientation glitch more properly.
this code is improved version of what #Buntupana posted
Try to setRequestedOrientation to SCREEN_ORIENTATION_SENSOR when exit from fullscreen !
setting OrientationEventListener may cause some unexpected resources usage.

Android determine screen orientation at runtime

Here's a pseudo code to detect screen rotate event, and decide to retain or changes the screen orientation.
public boolean onOrientationChanges(orientation) {
if(orientation == landscape)
if(settings.get("lock_orientation"))
return false; // Retain portrait mode
else
return true; // change to landscape mode
return true;
}
How do I make similar things in Android?
EDIT:
I'm actually looking answer on Where to handle orientation changes. I do not want to fix the orientation by adding screenOrientation="portrait".
I need something, similar to onConfigurationChanges(), where I can handle the orientation, but do no need me to manually redraw the view.
You need a Display instance firstly:
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
Then orientation may be called like this:
int orientation = display.getOrientation();
Check orientation as your way and use this to change orientation:
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
I hope it helps.
Update:
Okay, let's say you've an oAllow var which is Boolean and default value is False.
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getOrientation();
switch(orientation) {
case Configuration.ORIENTATION_PORTRAIT:
if(!oAllow) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
break;
case Configuration.ORIENTATION_LANDSCAPE:
if(!oAllow) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
break;
}
}
You can add more choices.
I didn't try this sample, but at least tells you some clues about how to solve. Tell me if you got any error.
UPDATE
getOrientation() is already deprecated see here. Instead Use getRotation(). To check if the device is in landscape mode you can do something like this:
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE))
.getDefaultDisplay();
int orientation = display.getRotation();
if (orientation == Surface.ROTATION_90
|| orientation == Surface.ROTATION_270) {
// TODO: add logic for landscape mode here
}
Try running
getResources().getConfiguration().orientation
From your context object to figure out what is the screen orientation at runtime, the possible values are documented here
In order to catch the orientation change event you can find the answer in the Android Dev Guide: Handling the Configuration Change Yourself
From the guide :
For example, the following manifest code declares an activity that
handles both the screen orientation change and keyboard availability
change:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration. By reading fields in the Configuration, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
...
if (this.getWindow().getWindowManager().getDefaultDisplay()
.getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
// portrait mode
} else if (this.getWindow().getWindowManager().getDefaultDisplay()
.getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
// landscape
}
You don't need to intercept the event and then override it. Just use:
// Allow rotation
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
// Lock rotation (to Landscape)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
Points to note here are, if on Jellybean and above this will allow a 180 degree rotation when locked. Also when unlocked this only allows rotation if the user's master settings is to allow rotation. You can forbid 180 degree rotations and override the master settings and allow rotation, and much much more, so check out the options in ActivityInfo
In addition, if you have pre-set that there is to be no rotation, then your activity will not be destroyed and then restarted, just for you to set the orientation back which will again cause the activity to be restarted; Thus setting what you want in advance can be much more efficient.
Pre Jellybean use ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE -- no 180 degree rotation with this.
Check your android screen orientation at Runtime:
ListView listView = (ListView) findViewById(R.id.listView1);
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
//do work for landscape screen mode.
listView.setPadding(0, 5, 0, 1);
} else if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
//Do work for portrait screen mode.
listView.setPadding(1, 10, 1, 10);
}
Another solution to determine screen orientation:
public boolean isLandscape() {
return Resources.getSystem().getDisplayMetrics().widthPixels - Resources.getSystem().getDisplayMetrics().heightPixels > 0;
}

Categories

Resources