Reputation: 1279
Is there a way to lock orientation during runtime? For example I'd like to allow the user to lock the screen to landscape if the user currently in landscape and toggle the menu option.
Upvotes: 110
Views: 82196
Reputation: 2591
Here is the Xamarin conversion of @pstoppani 's answer above.
NOTE: this is for a Fragment, replace Activity. with this. if used within an activity.
public void LockRotation()
{
ScreenOrientation orientation;
var surfaceOrientation = Activity.WindowManager.DefaultDisplay.Rotation;
switch (surfaceOrientation) {
case SurfaceOrientation.Rotation0:
orientation = ScreenOrientation.Portrait;
break;
case SurfaceOrientation.Rotation90:
orientation = ScreenOrientation.Landscape;
break;
case SurfaceOrientation.Rotation180:
orientation = ScreenOrientation.ReversePortrait;
break;
default:
orientation = ScreenOrientation.ReverseLandscape;
break;
}
Activity.RequestedOrientation = orientation;
}
public void UnlockRotation()
{
Activity.RequestedOrientation = ScreenOrientation.Unspecified;
}
This is untested as went with a different approach before used it, but may be of use.
Upvotes: 0
Reputation: 7203
Here is my code, you could lock with one of these methods your screen and once finished the task unlock it with unlockOrientation:
/** Static methods related to device orientation. */
public class OrientationUtils {
private OrientationUtils() {}
/** Locks the device window in landscape mode. */
public static void lockOrientationLandscape(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
/** Locks the device window in portrait mode. */
public static void lockOrientationPortrait(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
/** Locks the device window in actual screen mode. */
public static void lockOrientation(Activity activity) {
final int orientation = activity.getResources().getConfiguration().orientation;
final int rotation = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
// Copied from Android docs, since we don't have these values in Froyo 2.2
int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;
// Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO
if (!BuildVersionUtils.hasGingerbread()) {
SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90){
if (orientation == Configuration.ORIENTATION_PORTRAIT){
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270)
{
if (orientation == Configuration.ORIENTATION_PORTRAIT){
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE){
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
}
/** Unlocks the device window in user defined screen mode. */
public static void unlockOrientation(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
}
}
Upvotes: 6
Reputation: 1918
Alternative to @pstoppani answer with support for tablets (As with @pstoppani answer, this will only work on devices >2.2)
-Tested on Samsung Galaxy SIII
and Samsung Galaxy Tab 10.1
public static void lockOrientation(Activity activity) {
Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
int tempOrientation = activity.getResources().getConfiguration().orientation;
int orientation = 0;
switch(tempOrientation)
{
case Configuration.ORIENTATION_LANDSCAPE:
if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
else
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
break;
case Configuration.ORIENTATION_PORTRAIT:
if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270)
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
else
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
activity.setRequestedOrientation(orientation);
}
Upvotes: 27
Reputation: 2561
This works on devices with reverse portrait and reverse landscape.
Lock orientation:
int orientation = getActivity().getRequestedOrientation(); int rotation = ((WindowManager) getActivity().getSystemService( Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); switch (rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; default: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; } getActivity().setRequestedOrientation(orientation);
Unlock orientation:
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Upvotes: 54
Reputation: 2715
Be careful of the difference between what getConfiguration returns and what setRequestedOrientation wants - they are both int, but they are coming from different constant definitions.
Here's how to lock the current orientation, while allowing 180 degree flips
int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
Upvotes: 111
Reputation: 9608
I seemed to had have a similar case. I wanted to support any orientation, but I needed to stay in the current orientation after a certain point in the workflow. My solution was:
At entry of the protected workflow:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
At exit of the protected workflow:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Upvotes: 28
Reputation: 11313
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Called on an activity, will lock it to landscape. Look for the other flags in the ActivityInfo class. You can lock it back to portrait or make it sensor/slider driven.
More info here: http://www.devx.com/wireless/Article/40792
Upvotes: 143