我的应用程序包含许多活动,并且具有适合手机大小(SFF)和平板电脑大小(LFF)设备的布局。对于LFF设备,框架在方向改变时自动重建活动(横向< - >肖像)工作正常并且做我想要的。在SFF设备上操作时,我可以使用Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
将方向锁定为纵向。
在SFF设备上运行时,我希望在设备物理旋转到横向时启动不同的活动。 (让我们暂时讨论在轮换时启动不同活动是否是一个好的设计原则。)
最初我使用OrientationEventListener
来监控旋转,但是在SFF设备的情况下,这种情况会失败,其“自然”方向是横向的。 OrientationEventListener.onOrientationChanged()
会报告0度(+/- 45),WindowManager.getDefaultDisplay().getRotation()
会在横向时报告Surface.ROTATION_0
。我无法找到确定设备“自然”方向的方法,以便补偿报告的旋转值。有几个SO问题可以讨论这个问题,但似乎都没有一个令人满意的答案。
另一种选择是在清单中使用android:configChanges="orientation|screenSize"
并在onConfigurationChanged()
中捕捉方向更改。这个问题是它破坏了LFF设备的默认行为,我希望保留它。一个可怕的黑客确实存在:使用LFF和SFF版本复制清单中的每个活动,一个有一个没有设置android:configChanges
的活动,然后让活动在每次启动新活动时选择适当的版本。 / p>
我当前的解决方案既不使用android:configChanges
也不使用setRequestedOrientation()
和OrientationEventListener
。相反,我有一个布尔资源is_landscape
,在values-land
中定义,我在相关活动onCreate()
中对此进行测试。这有一个缺点,就是在旋转到风景时:
任何人都可以提出更好的解决方案,包括可能发现设备的“自然”方向吗?我需要这个才能恢复到Android 4.0。
答案 0 :(得分:0)
您必须使用getRotation
和getResources().getConfiguration()
的组合检查天然食物。
public int getDefaultOrientation() {
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Configuration config = getResources().getConfiguration();
int rotation = windowManager.getDefaultDisplay().getRotation();
if ( ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
return Configuration.ORIENTATION_LANDSCAPE;
} else {
return Configuration.ORIENTATION_PORTRAIT;
}
}