是否有一种在运行时锁定屏幕方向的方式?比如,如果用户当前处于横屏状态并切换菜单选项,则我希望允许用户将屏幕锁定为横屏。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
在一个活动中调用这个方法,将会把它锁定为横屏模式。在ActivityInfo类中查找其他标志,你可以将其锁定为竖屏或者设置为传感器/滑动驱动。
要注意getConfiguration返回值与setRequestedOrientation想要的值之间的差异 - 它们都是int类型,但来自不同的常量定义。
下面介绍如何锁定当前方向,同时允许180度翻转。
int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
此功能适用于具有反向竖屏和反向横屏的设备。
锁定方向:
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);
解锁方向:
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
"获取屏幕从其“自然”方向的旋转信息。"
来源。因此,在手机上,表示 ROTATION_0 为纵向是正确的,但在平板电脑上,其“自然”方向很可能是横向,ROTATION_0 应返回横向而不是纵向。请注意,本文中的"portrait"指纵向,"landscape"指横向。 - jp36我似乎遇到了类似的情况。我想支持任何方向,但在工作流程的某个点之后需要保留当前方向。我的解决方法是:
进入受保护工作流程时:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
在受保护的工作流程结束时:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
对于 @pstoppani 的回答,这里提供了支持平板电脑的替代方案(和 @pstoppani 的回答一样,这仅适用于设备版本 >2.2)
- 在 Samsung Galaxy SIII
和 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);
}
rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90
,以及为什么要用 rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_270
来检查。所以我有两个疑问:第一,为什么在第二个情况下要使用 ROTATION_0
而不是 ROTATION_180
;另一个疑问是为什么要将 0 度与 90 度进行比较而不是 180 度? - AndyBoy||
检查基于设备报告的横屏和竖屏处理两种可能的默认方向。 - jp36这是我的代码,你可以使用其中一种方法锁定屏幕,完成任务后再使用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);
}
}
这是@pstoppani上面回答的Xamarin转换版本。
注意:这是用于Fragment的,如果在Activity中使用,请将Activity.替换为this.
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;
}
这个还没有经过测试,因为之前采用了不同的方法,但可能会有用。