【问题标题】:Android: manual screen orientation without restarting the activity?Android:手动屏幕方向而不重新启动活动?
【发布时间】:2013-03-26 08:22:56
【问题描述】:

我需要制作一个应用程序来播放视频,并带有一个用于全屏播放视频的按钮。该按钮用于手动切换视频显示的横向和纵向。我们不希望自动旋转检测。所以Manifest文件设置如下。

<activity
    android:name=".VideoActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden"/>

我用过

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); 或setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);

手动设置方向。它可以工作,但它会重新启动活动 - 发现调用了 onCreate()。所以视频播放意外地从头开始。我不能让它像使用onConfigurationChanged() 一样平滑 - 自动旋转检测方法。

那么如何在不重新启动活动的情况下手动更改屏幕方向?

谢谢。

【问题讨论】:

标签: android android-activity orientation restart manual


【解决方案1】:

手动改变方向:

<activity
    android:name=".VideoDetails"
    android:configChanges="orientation"/>

public class VideoDetails extends Activity {
    ...
    onStart() {
        setRequestedOrientation(orientation);
    }
    onConfigurationChanged(Configuration newConfig){
        // do stuff for orientation change.
    }
    onClick() {
        setRequestedOrientation(orientation);
    }
}

对于自动方向检测:

<activity
    android:name=".VideoDetails"
    android:configChanges="orientation"/>

public class VideoDetails extends Activity {
    ...
    onConfigurationChanged(Configuration newConfig){
        // do stuff for orientation change.
    }
}

【讨论】:

    【解决方案2】:

    http://developer.android.com/guide/topics/resources/runtime-changes.html。您可以查看标题自行处理配置更改

    下的链接
    <activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">
    

    现在,当这些配置之一发生更改时,MyActivity 不会重新启动。相反,MyActivity 收到对 onConfigurationChanged() 的调用。此方法传递一个配置对象,该对象指定新的设备配置。

     android:configChanges="orientation|screenSize" (andorid 3.2 and above screen size also changes. add this)
    

    假设您的视频时长为 10 分钟。视频播放到 5 分钟并且方向发生变化,您知道它已经播放到 5 分钟。

    您可以在 onSaveInstanceState() 中保存视频的实际进度,并从 Bundle 中获取 onRestoreInstanceState() 中保存的数据,之后您可以使用进度数据开始播放,如果没有则从头开始播放数据已保存。

    当方向改变时,活动被销毁并重新创建。如果您想保存数据并保留,您可以执行以下操作以保存大量数据

     @Override
     public Object onRetainNonConfigurationInstance() {
     final MyDataObject data = collectMyLoadedData();
     return data;
     }
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
    if (data == null) {
        data = loadMyData();
    }
    
    }
    

    对于小数据集

     @Override
     public void onSaveInstanceState(Bundle savedInstanceState) {
     super.onSaveInstanceState(savedInstanceState);
     // Save UI state changes to the savedInstanceState.
     // This bundle will be passed to onCreate if the process is
     // killed and restarted.
     savedInstanceState.putString("NICK_NAME", Name);//save nick name
     }
    
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     // Restore UI state from the savedInstanceState.
     // This bundle has also been passed to onCreate.
     Name = savedInstanceState.getString("NICK_NAME");//restore nick name
     }
    

    检查方向

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    
    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
    }
    

    VideoView in Android。在这种情况下,视频也是从服务器流式传输的。检查接受的答案(commonsware answer)。和我建议的一模一样。

    【讨论】:

    • 谢谢。您使用onSaveInstanceState() 和onRestoreInstanceState() 的方法是解决方案之一。但我担心的是视频播放的流畅性,因为我的应用程序从服务器播放视频流。重新连接和视频搜索时间会使视频播放不连续。
    • @user1835097 检查最后一个链接。用户还从服务器流式传输视频。检查接受的答案。
    【解决方案3】:

    首先将 android:configChanges 节点添加到您的 Activity's 清单节点

    android:configChanges="keyboardHidden|orientation"
    

    更多信息请查看this链接

    【讨论】:

    • 谢谢。您的方法似乎自动检测系统的方向变化。它可以防止重新启动活动。但我不想要自动检测。我需要手动设置。
    • @user1835097 然后你可以通过覆盖 Activity.onConfigurationChanged
    • @user1835097 检查此链接c0deattack.wordpress.com/2010/12/25/…
    【解决方案4】:

    添加标签

    "android:configChanges="keyboard|keyboardHidden|orientation|screenSize|navigation" for your activity in Manifest.xml,
    

    并重写方法

    public void onConfigurationChanged(Configuration newConfig) {}
    

    如果您需要在orientationchange 上更改布局,请查看这个 replace layout on orientation change

    【讨论】:

      【解决方案5】:

      在方向改变后重启应用是不可避免的。

      将与视频状态相关的变量保留在 Application 上,以便 Activity 不会在开始时重新开始播放。

      此代码来自我为测试此答案而制作的示例应用程序。

      public class MyApplication extends Application {
      int counter;
      @Override
      public void onCreate() {
          super.onCreate();
          counter = 0;
          }
      }   
      

      在清单中添加应用程序

      <application
          android:allowBackup="true"
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme"
          android:name="com.example.orientationchange.MyApplication" >
          <activity
       ...
      

      在 Activity 中使用:

      public class MainActivity extends Activity {
      
      TextView output;
      MyApplication app ;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          app = (MyApplication) getApplication();
          setContentView(R.layout.activity_main);
          output = (TextView) findViewById(R.id.output);
          //A counter thread used to test the solution.
          new CounterTask().execute( 100 );
      }
       ...
      

      现在轮换不会清除状态变量。

      您也可以使用 Preferences 来获得更多代码量的解决方案来保留状态。首选项还将记住从一次使用应用程序到另一次使用应用程序的状态,其中应用程序状态在应用程序的 onDestroy() 中被清除。

      【讨论】:

        【解决方案6】:

        我一直在寻找解决方案,并且对我来说,将 Manifest 中的方向定义为锁定:

        <activity
            android:name=".VideoActivity"
            android:screenOrientation="locked"
            android:configChanges="keyboardHidden"/>
        

        即使您调用 setRequestedOrientation()

        ,这也会阻止重新创建 Activity

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多