调用setRequestedOrientation()以在横向模式下显示时,活动创建两次

时间:2014-10-25 15:05:22

标签: android

我有Android应用程序,我想强制平板电脑(sw600dp及更高版本)以横向模式显示,手机以纵向模式显示,所以我处理onCreate of the BaseActivity class

boolean isTablet= getResources().getBoolean(R.bool.isTablet);
if (isTablet) {
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else { 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} 

我在bools.xml文件中放入“isTablet”的方式并将其放入

手机文件夹

   <resources>
        <bool name="isTablet">false</bool>
   </resources>
平板电脑

values-sw600dp

   <resources>
        <bool name="isTablet">true</bool>
   </resources>

在AndroidManifest中我使用

android:screenOrientation="nosensor"

确保禁用设备方向的传感器。

似乎我的方法工作得很好(平板电脑的横向和手机的肖像)但是当我在Nexus 7上运行我的应用程序时出现问题 - 我的活动创建了两次。这些步骤是:

  1. 肖像中的洞Nexus 7(如果我在风景中保持平板电脑就没问题)
  2. 然后运行应用
  3. 我发现问题是方法setRequestedOrientation()(上面有两个步骤)。所以我不想再调用那种方法了。我尝试在AndroidManifest中设置方向,如:

    android:screenOrientation="@integer/orientation"
    

    由于: SCREEN_ORIENTATION_LANDSCAPE = 0 SCREEN_ORIENTATION_PORTRAIT = 1

    我在integers.xml文件中声明“orientation”并将其放入

    手机文件夹

    <resources>
        <integer name="orientation">1</integer>
    </resources>
    
    平板电脑

    values-sw600dp

    <resources>
        <integer name="orientation">0</integer>
    </resources>
    

    同样,我的方法往往工作正常但我发现AndroidMenifest只知道文件夹中的“方向”,而不是 values-sw600dp 文件夹。我不希望我的活动打2次。你有这样的问题吗?你能解决吗?感谢。

2 个答案:

答案 0 :(得分:1)

来自文档setRequestedOrientation(int)

  

如果活动当前处于前台或以其他方式影响   屏幕方向,屏幕将立即更改   (可能导致活动重新启动

它没有被重新创建,它只是重新启动以解释方向的变化。

所以,只需将不应运行两次的功能移至onCreate即可。

答案 1 :(得分:0)

Simas的回答是正确的,让我解释一下。

假设您将设备纵向放置,然后启动Activity,然后在onCreate中调用以下命令:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

然后,您基本上是在告诉设备应该旋转(因为您将设备保持在纵向模式)。

但是,如果您在启动Activity之前以横向方式握住设备并按上述相同的方式进行调用,则设备无需旋转,因为它已经处于横向模式。

众所周知,旋转设备会导致Activity被销毁并重新创建。呼叫setRequestedOrientation时也是如此(如果设备当前不在请求的位置)。


所以。如何处理。

  • 第一个也是最明显的选择是不致电 setRequestedOrientation。而是使用 onSaveInstanceState存储您的值,并 onRestoreInstanceState恢复存储在其中的值 捆绑包等。
  • 就我而言,由于我的应用程序的设计,我不得不使用 setRequestedOrientation,因为我正在根据 选定的视频尺寸。

    这是我完成此任务的方式。

    由于我想自己处理旋转,因此我首先必须添加 在我的清单中:

    android:configChanges="orientation|screenSize|keyboardHidden"
    

    这样做可以覆盖configuration changes。如 在文档中提到的-This technique should be considered a last resort

    接下来,当我要旋转 设备进行景观设计,并调用以下命令:

    private void rotateScreen(Uri vidUri) {
        try {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            Bitmap bmp;
            retriever.setDataSource(this, vidUri);
            bmp = retriever.getFrameAtTime();
    
            videoWidth = bmp.getWidth();
            videoHeight = bmp.getHeight();
    
            if (videoWidth > videoHeight) {
                setContentView(R.layout.activity_video_player_land);
                this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
            if (videoWidth < videoHeight) {
                setContentView(R.layout.activity_video_player);
                this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
    
        } catch (RuntimeException ex) {
            Log.e("MediaMetadataRetriever", "- Failed to rotate the screen");
    
        }
    }
    

    由于我的画像布局中的所有内容都在我的风景中 布局,我不必担心找不到资源。


我使用的解决方案不适用于所有应用程序(如果您有不同的资源用于不同的方向),但就我而言,我使用所有相同的资源,调整大小并四处移动以更好地适应横向视图。