为啥屏幕旋转 180 度不算作配置更改?

Posted

技术标签:

【中文标题】为啥屏幕旋转 180 度不算作配置更改?【英文标题】:Why 180 degree rotation of the screen is not counted as a config change?为什么屏幕旋转 180 度不算作配置更改? 【发布时间】:2017-06-13 09:48:24 【问题描述】:

为什么屏幕快速旋转 180 度不算作配置更改,因此不会触发 Activity.onCreate() !?所以我不能重新定位我的相机视图!如果您旋转 90 度,则每次都会触发配置更改。 我将省略源代码,因为我的清单没有 configChanges 也没有 orientation 属性。活动也没什么特别的。这似乎是一种预期的行为,但我没有找到任何官方信息。

设备:硬件 Nexus 5X

平台android 7.1.1

清单:

<supports-screens
    android:anyDensity="true"
    android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="false"
    android:xlargeScreens="true" />

<application
    android:name="xyz.MyApp"
    android:allowBackup="true"
    android:backupAgent=".provider.MyBackupAgent"
    android:hardwareAccelerated="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:restoreAnyVersion="true"
    android:theme="@style/AppTheme"
    android:uiOptions="splitActionBarWhenNarrow"
    tools:replace="android:icon" >

<activity android:name="xyz.MyActivity"
        android:label="asdf"
        android:theme="@style/Theme" />

styles.xml:

<style name="Theme" parent="Theme.AppCompat.NoActionBar">
    <item name="actionBarIconColor">#fff</item>
    <item name="actionBarInsetStart">@dimen/keyline_2</item>
</style>

styles-v19.xml:

<style name="Theme" parent="Theme.AppCompat.NoActionBar">
    <item name="actionBarIconColor">#fff</item>
    <item name="actionBarInsetStart">@dimen/keyline_2</item>
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

【问题讨论】:

因为旋转 180 度使其保持纵向(或横向),所以不需要。 好吧,但它会使相机预览颠倒! 【参考方案1】:

您应该在AndroidManifest.xml 中为您的活动指定android:screenOrientation="fullSensor" 正如here 所述,默认方向是sensor,它忽略了反向纵向方向。 fullSensor 允许所有 4 个方向

更新:上面的回答不能解决问题。核心问题是方向改变 180 度(即从横向到反向横向)不会触发重新创建活动。这是预期的行为。在常见情况下,横向布局与反向横向布局没有区别。 如果您想在旋转 180 后更改某些视图,可以使用OrientationEventListener

示例:

final WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

OrientationEventListener orientationEventListener = new OrientationEventListener(this,
                SensorManager.SENSOR_DELAY_NORMAL) 
            @Override
            public void onOrientationChanged(int orientation) 
                if (orientation == ORIENTATION_UNKNOWN) 
                    return;
                
                Display display = mWindowManager.getDefaultDisplay();
                int rotation = display.getRotation();
                if (rotation != mLastRotation) 
                    // do something with your views
                    mLastRotation = rotation;
                
            
        ;

 if (orientationEventListener.canDetectOrientation()) 
     orientationEventListener.enable();
 

如果你的 minSdk 是 17+,你也可以使用 DisplayListener#onDisplayChanged 回调

【讨论】:

@WindRider 你能用你的活动代码和 AndroidManifest.xml 更新你的问题吗? 我很确定您可以通过任何活动重现它。我用其他活动和其他应用程序做到了。这似乎是平台预期的行为。 @WindRider 请检查您的清单。我制作的示例应用程序包含android:screenOrientation="fullSensor" 的活动。它在带有 android 7.1.1 的 Nexus 5x 上按预期工作(所有 4 个方向) 所有 4 个方向都不是这样。问题案例是快速倒转。我刚刚在问题中添加了一些 xml。 @WindRider 我在您的清单中看不到 android:screenOrientation 属性。你真的试过了吗?【参考方案2】:

请在AndroidManifest文件中使用这个:

android:screenOrientation="sensorLandscape"

【讨论】:

以上是关于为啥屏幕旋转 180 度不算作配置更改?的主要内容,如果未能解决你的问题,请参考以下文章

如何将整个网页旋转90度,180度或270度?

android 屏幕旋转

在目标 c 中更改应用扩展的屏幕旋转

防止Android上的屏幕旋转

如何防止方向改变180度

Android屏幕旋转不生效