這是我寫的一個類,用於處理鎖定和解鎖屏幕方向。我從開關按鈕的checkedChangedListener調用toggleScreenOrientationLock(this, prefs, isChecked)
,並從onCreate()調用restoreScreenLock(this, prefs)
。在這兩種情況下,您的活動都是this
,而prefs
是一個SharedPrefences
對象,用於保存有關鎖定狀態的信息。
該代碼的複雜部分是getScreenOrientation()
函數which I stole from and cleaned up from here。我會試着解釋這個工作原理背後的邏輯。
當我們將設備的方向設置爲setRequestedOrienation()
時,我們需要知道設備是處於橫向還是縱向模式,並且我們需要知道它是否是反向(旋轉180度)。
使用getResources().getConfiguration().orientation
將回答我們所在的方向。如果我們可以考慮設備的旋轉,我們可以判斷它是否旋轉了180°。不幸的是,取決於設備,ROTATE_0可能是縱向或橫向。手機通常將ROTATE_0映射到肖像,並將平板電腦映射到景觀。
因此,此處使用的解決方案是使用屏幕尺寸來確定它是橫向還是縱向。如果屏幕寬度大於高度,則我們推斷設備處於橫向模式,反之亦然。然後我們可以考慮旋轉來確定方向是否顛倒。
例如,如果屏幕寬度比高,那麼我們知道我們處於橫向模式。如果旋轉是0或180(在代碼的邏輯中,這等於!isRotatedOrthogonally),那麼我們知道0是LANDSCAPE,而180是REVERSE_LANDSCAPE。
It has been noted elsewhere這不適用於所有設備,因爲無論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();
}
}
你嘗試過'setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); '和'setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); '? –
你需要哪種定向模式? – GrIsHu
我想鎖定方向。如果它是風景,我想鎖定它的風景,如果它是肖像我想鎖定它肖像。兩者都不起作用。所以我試圖鎖定到橫向方向進行測試。 – user2682527