在不重新启动当前活动的情况下调用方向更改活动

时间:2015-11-27 14:47:53

标签: android rotation

我的应用程序包含许多活动,并且具有适合手机大小(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。

1 个答案:

答案 0 :(得分:0)

您必须使用getRotationgetResources().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;
    }
}