Java 以编程方式在android中锁定方向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20209511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
orientation lock in android programmatically
提问by user2682527
I have the following code.
我有以下代码。
Java
爪哇
public void lockScreenOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
public void unlockScreenOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
I am calling these functions from javascript. Control is entering these methods. However the orientation is not locked.
我正在从 javascript 调用这些函数。控制正在进入这些方法。但是方向没有锁定。
I have tried following to lock the orientation
我试过跟随锁定方向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
None of these seem to work. Any pointers would be helpful.
这些似乎都不起作用。任何指针都会有所帮助。
回答by Anonsage
I've created a few utility methods to help deal with orientation locking, feel free to use this class.
我已经创建了一些实用方法来帮助处理方向锁定,请随意使用这个类。
Example use:
使用示例:
- In an Activity:
OrientationUtils.lockOrientationPortrait(MyActivityName.this)
- In a Fragment:
OrientationUtils.lockOrientationLandscape(getActivity())
- 在活动中:
OrientationUtils.lockOrientationPortrait(MyActivityName.this)
- 在一个片段中:
OrientationUtils.lockOrientationLandscape(getActivity())
Code:
代码:
/** 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);
}
/** Allows user to freely use portrait or landscape mode. */
public static void unlockOrientation(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
Here's my full OrientationUtils class on GitHub that can be used in any Android app: https://github.com/danialgoodwin/android-simply-advanced-helper/blob/master/SimplyAdvancedHelperLibrary/src/net/simplyadvanced/utils/OrientationUtils.java
这是我在 GitHub 上的完整 OrientationUtils 类,可用于任何 Android 应用程序:https: //github.com/danialgoodwin/android-simply-advanced-helper/blob/master/SimplyAdvancedHelperLibrary/src/net/simplyadvanced/utils/OrientationUtils。爪哇
回答by Robert Liberatore
This is a class I wrote to handle locking and unlocking the screen orientation. I call toggleScreenOrientationLock(this, prefs, isChecked)
from a toggle button's checkedChangedListener, and restoreScreenLock(this, prefs)
from onCreate(). In both cases this
is your activity and prefs
is a SharedPrefences
object, used for saving information about the state of the lock.
这是我编写的用于处理锁定和解锁屏幕方向的类。我toggleScreenOrientationLock(this, prefs, isChecked)
从切换按钮的checkedChangedListener 和restoreScreenLock(this, prefs)
onCreate()调用。在这两种情况下this
是你的活动,prefs
是一个SharedPrefences
对象,用于保存关于锁的状态信息。
The complicated part pf the code is the getScreenOrientation()
function, which I stole from and cleaned up from here. I'll try to explain logic behind how this works.
代码中复杂的部分是getScreenOrientation()
函数,我从这里窃取并清理了它。我将尝试解释其工作原理背后的逻辑。
When we set the device's orientation with setRequestedOrienation()
, we need to know if the device is in landscape or portrait mode, and we need to know if it's a reverse orientation (rotated 180 degrees).
当我们用 设置设备的方向时setRequestedOrienation()
,我们需要知道设备是处于横向模式还是纵向模式,我们需要知道它是反向(旋转 180 度)。
Using getResources().getConfiguration().orientation
will answer the question of which orientation we're in. If we could factor in the rotation of the device, we could tell whether it was rotated 180 or not. Unfortunately, depending on the device, ROTATE_0 might be portrait or landscape. Phones typically map ROTATE_0 to portrait, and tablets to landscape.
使用getResources().getConfiguration().orientation
将回答我们处于哪个方向的问题。如果我们可以考虑设备的旋转,我们就可以判断它是否旋转了 180 度。不幸的是,根据设备,ROTATE_0 可能是纵向或横向。手机通常将 ROTATE_0 映射到纵向,将平板电脑映射到横向。
So the solution used here is to use the screen dimensions to determine if it is in landscape or portrait instead. If the screen is wider than it is tall, then we infer that the device is in a landscape orientation, and vice versa for portrait. Then we can factor in the rotation to figure out whether the orientation is reversed or not.
所以这里使用的解决方案是使用屏幕尺寸来确定它是横向还是纵向。如果屏幕宽度大于高度,则我们推断设备处于横向,反之亦然。然后我们可以考虑旋转来确定方向是否反转。
For example, if the screen is wider than it is tall, then we know we're in a landscape orientation. If the rotation is either 0 or 180 (in the code's logic, this is equal to !isRotatedOrthogonally), then we know that 0 is LANDSCAPE and 180 is REVERSE_LANDSCAPE.
例如,如果屏幕宽度大于高度,那么我们就知道我们处于横向。如果旋转是 0 或 180(在代码的逻辑中,这等于 !isRotatedOrthogonally),那么我们知道 0 是 LANDSCAPE,180 是 REVERSE_LANDSCAPE。
It has been noted elsewherethat this won't work across all devices, since whether 90 or 270 is the reversed orientation is device specific. But this is still probably the best you're going to do; at worst, one orientation will rotate 180 degrees when you lock it, which is what would likely happen if tried locking the screen any other way.
其他地方已经指出,这不适用于所有设备,因为 90 或 270 是反向方向是特定于设备的。但这仍然可能是您要做的最好的事情;在最坏的情况下,当您锁定一个方向时,它会旋转 180 度,如果尝试以任何其他方式锁定屏幕,可能会发生这种情况。
public class ScreenLocker {
final private static String ROTATION_LOCKED_KEY = "LockedOrientationVal";
final private static String ROTATION_IS_LOCKED_KEY = "IsRotationLocked";
final private static String ROTATION_SAVED_KEY = "SavedOrientationVal";
public static int getScreenOrientation(Activity activity) {
final Display display = activity.getWindowManager().getDefaultDisplay();
final int rotation = display.getRotation();
Point size = new Point();
display.getSize(size);
final boolean isWiderThanTall = size.x > size.y;
final boolean isRotatedOrthogonally = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
int orientation;
if (isRotatedOrthogonally) {
if (isWiderThanTall)
orientation = (rotation == Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
else
orientation = (rotation == Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; // normal and reversed switched intended
}
else {
if (isWiderThanTall)
orientation = (rotation == Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
else
orientation = (rotation == Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
return orientation;
}
public static void toggleScreenOrientationLock(Activity activity,SharedPreferences prefs, boolean lock) {
if(lock)
lockScreenOrientation(activity, prefs);
else
unlockScreenOrientation(activity, prefs);
}
// call this from your activity's onCreate() or onResume()
public static boolean restoreScreenLock(Activity activity, SharedPreferences prefs) {
final boolean isLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);
final int previousLockedOrientation = prefs.getInt(ROTATION_LOCKED_KEY, -999);
if(isLocked && previousLockedOrientation != -999) {
prefs.edit().putInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation()).apply();
activity.setRequestedOrientation(previousLockedOrientation);
return true;
}
return false;
}
private static void lockScreenOrientation(Activity activity, SharedPreferences prefs) {
final int currentOrientation = activity.getRequestedOrientation();
final int lockOrientation = getScreenOrientation(activity);
// checking isCurrentlyLocked prevents the ROTATION_LOCKED_KEY and ROTATION_SAVED_KEY
// becoming identical, which results in the screen not being able to be unlocked.
final boolean isCurrentlyLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);
if(!isCurrentlyLocked) {
activity.setRequestedOrientation(lockOrientation);
prefs.edit()
.putInt(ROTATION_SAVED_KEY, currentOrientation)
.putInt(ROTATION_LOCKED_KEY, lockOrientation)
.putBoolean(ROTATION_IS_LOCKED_KEY, true)
.apply();
}
}
private static void unlockScreenOrientation(Activity activity, SharedPreferences prefs) {
final int savedOrientation = prefs.getInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation());
activity.setRequestedOrientation(savedOrientation);
prefs.edit().putBoolean(ROTATION_IS_LOCKED_KEY, false).apply();
}
}
回答by Juni
Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
Locks the screen (activity) in whatever the orientation it was.
Requires API Level >= 18
以任何方向锁定屏幕(活动)。
需要 API 级别 >= 18
回答by Tokar
Here's another simple solution that works well for me.
这是另一个对我很有效的简单解决方案。
private void orientationManager(boolean lock)
{
int currentOrientation = getResources().getConfiguration().orientation;
if(lock)
{
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
else
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
I needed to lock orientationManager(true);
the current screen orientation when dialogs were opened and unlock orientationManager(false);
when the dialog was closed.
我需要orientationManager(true);
在打开对话框时锁定当前屏幕方向,并orientationManager(false);
在关闭对话框时解锁。