显示屏幕方向的后备

Ten*_*r04 7 android

Android清单文档中,有多种不同的指定方式screenOrientation:

  • landscape
  • sensorLandscape 在API 9中添加
  • userLandscape 在API 18中添加

我该如何指定userLandscape,但在旧版本的Android上,它可以回退sensorLandscape,甚至更旧的版本可以回归到landscape?我在文档中找不到如何做到这一点.

Vik*_*ram 9

我认为没有办法在清单本身中实现回退机制.

我建议您在清单中指定{userLandscape,sensorLandscape,landscape}之一.然后,在运行时检查版本并即兴发挥.

说,你决定参加android:screenOrientation="userLandscape"清单.

在您的活动中onCreate(Bundle),在设置内容之前:

int sdkInt = Build.VERSION.SDK_INT;

// if we're running on some API level within [9, 18), use `sensorLandscape`
if (sdkInt >= Build.VERSION_CODES.GINGERBREAD /* 9 */ 
        && sdkInt < Build.VERSION_CODES.JELLY_BEAN_MR2 /* 18 */) {
    setRequestedOrientation(
            ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if (sdkInt < Build.VERSION_CODES.GINGERBREAD /* 9 */) {
    setRequestedOrientation(
            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}

// API 18 or above - handled in manifest

setContentView(R.layout.whatever);
Run Code Online (Sandbox Code Playgroud)

希望有人能提出比这更好的解决方案.这似乎是暴力.

编辑:

尝试了不同的方法-从我所知道的(我可能是错在这里),枚举等userLandscape,sensorLandscape等等不会改变值.他们目前的立场:

<attr name="screenOrientation">
    <enum name="unspecified" value="-1" />
    <enum name="landscape" value="0" />
    <enum name="portrait" value="1" />
    <enum name="user" value="2" />
    <enum name="behind" value="3" />
    <enum name="sensor" value="4" />
    <enum name="nosensor" value="5" />
    <enum name="sensorLandscape" value="6" />
    <enum name="sensorPortrait" value="7" />
    <enum name="reverseLandscape" value="8" />
    <enum name="reversePortrait" value="9" />
    <enum name="fullSensor" value="10" />
    <enum name="userLandscape" value="11" />
    <enum name="userPortrait" value="12" />
    <enum name="fullUser" value="13" />
    <enum name="locked" value="14" />
</attr>
Run Code Online (Sandbox Code Playgroud)

所以,如果你要定义integer如下:

<!-- `0` for `landscape` -- defined in values/integers.xml -->
<integer name="customScreenOrientation">0</integer>

<!-- `6` for `sensorLandscape` -- defined in values-v9/integers.xml -->
<integer name="customScreenOrientation">6</integer>

<!-- `11` for `userLandscape` -- defined in values-v18/integers.xml -->
<integer name="customScreenOrientation">11</integer>
Run Code Online (Sandbox Code Playgroud)

然后,您可以将其@integer/customScreenOrientation用作android:screenOrientation活动标签中的值.

不用说它最好是一个黑客.如果有人可以确认枚举值的稳定状态screenOrientation,这可能是一个可行的解决方法 - 比在我的早期建议中包含多个活动的代码更可取.

又一个编辑:

我之前提到的第二种方法可以改进:

而不是多个integers.xml文件,创建3个styles.xml文件.我猜你已经有了 - values/styles.xml.创建values-v9/styles.xml&values-v18/styles.xml.

<!-- values/styles.xml -->
<style name="AppTheme" parent="@style/BaseTheme">
    <item name="android:screenOrientation">landscape</item>
</style>

<!-- values-v9/styles.xml -->
<style name="AppTheme" parent="@style/BaseTheme">
    <item name="android:screenOrientation">sensorLandscape</item>
</style>

<!-- values-v18/styles.xml -->
<style name="AppTheme" parent="@style/BaseTheme">
    <item name="android:screenOrientation">userLandscape</item>
</style>
Run Code Online (Sandbox Code Playgroud)

在此之后,创建values/integers.xml(一个文件)并定义一个整数customScreenOrientation:

<integer name="customScreenOrientation">?android:attr/screenOrientation</integer>
Run Code Online (Sandbox Code Playgroud)

您的活动标记将如下所示:

<activity
    ....
    android:theme="@style/AppTheme"
    android:screenOrientation="@integer/customScreenOrientation"/>
Run Code Online (Sandbox Code Playgroud)

这种方法优于第二种方法的优点是我们可以使用枚举代替硬编码值.同样,如果枚举值是一成不变的,这两种方法是等价的.如果他们确实改变了,第二种方法将失败而第三种方法继续进行.