最近用到了视频组件,需要设置横竖屏,所以现在把基础知识再梳理一下.
最简单的一句话搞横竖屏:
在AndroidManifest.xml中静态声明设置Activity的方向参数:
android:screenOrientation="portrait" //设置竖屏
android:screenOrientation="landscape"//横屏
android:screenOrientation="sensor"//根据传感器
android:screenOrientation="behind"//根据栈中前一个Activity方向保持一致
//还有更多,不常用,不过可以看出Android横竖屏切换搞出这么属性.还是很强大的;
/*
* The preferred screen orientation this activity would like to run in.
* From the {@link android.R.attr#screenOrientation} attribute, one of
* {@link #SCREEN_ORIENTATION_UNSPECIFIED},
* {@link #SCREEN_ORIENTATION_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_PORTRAIT},
* {@link #SCREEN_ORIENTATION_USER},
* {@link #SCREEN_ORIENTATION_BEHIND},
* {@link #SCREEN_ORIENTATION_SENSOR},
* {@link #SCREEN_ORIENTATION_NOSENSOR},
* {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT},
* {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT},
* {@link #SCREEN_ORIENTATION_FULL_SENSOR},
* {@link #SCREEN_ORIENTATION_USER_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_USER_PORTRAIT},
* {@link #SCREEN_ORIENTATION_FULL_USER},
* {@link #SCREEN_ORIENTATION_LOCKED},
*/
上述代码,需要在activity 标签上使用
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
</activity>
或者使用Java代码设置:
//获取设备当前方向
int currentO = getResources().getConfiguration().orientation;
//强制设置为横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//强制设置竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
需要注意是切换屏幕,不会保持默认的Activity的生命周期,发生变化时,Activity会被销毁重新创建.这通常会损失应用的性能,因此需要先保持UI状态,然后重建Activity.
解决这个重建问题需要
在AndroidManifest.xml 给Activity设置
android:configChanges="orientation|keyboardHidden"
orientation参数注册了设备方向变动的事件, keyboardHidden为键盘事件,需要一并设置,否则Activity也可能会在这些事件上导致重建.
一次从竖屏-横屏-竖屏的生命周期变化如下:
11-07 22:58:55.364 11537-11537/...MainActivity: onCreate
11-07 22:58:55.364 11537-11537/...MainActivity: onResume()
11-07 22:59:00.364 11537-11537/...MainActivity: onPause()
11-07 22:59:00.374 11537-11537/...MainActivity: onStop
11-07 22:59:00.374 11537-11537/...MainActivity: onDestroy()
11-07 22:59:00.484 11537-11537/...MainActivity: onCreate
11-07 22:59:00.494 11537-11537/...MainActivity: onResume()
11-07 22:59:04.154 11537-11537/...MainActivity: onPause()
11-07 22:59:04.154 11537-11537/...MainActivity: onStop
11-07 22:59:04.154 11537-11537/...MainActivity: onDestroy()
11-07 22:59:04.224 11537-11537/...MainActivity: onCreate
11-07 22:59:04.224 11537-11537/...MainActivity: onResume()
因此,我们需要在配置发生变化时,保存必要地数据,然后重新加载视图资源;
类似下面的伪代码:
@Override
protected void onCreate(Bundle b){
super.onCreate(b);
loadView();
}
...
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
saveState();
loadView();
}
public void saveState(){} //保存必要数据
public void loadView(){
setContentView(R.layout.main);
//根据新的变化,处理其他必要地UI改动
//恢复和保存的状态
}
写了这么多,但是Google说不建议这样使用…网上也很多方法说这么设置;
但是按照上述设置,我试过,我发现Acitvity的生命周期onConfigurationChanged并未调用;⊙﹏⊙b汗
后记:
至此困扰我将近两天的问题,Activity_A竖屏跳转Activity_B横屏,再finsh回到A,则A发生重建,为了不让A创建.用尽了网上千篇一律的解决方法都没有解决,
如果把xml的设置. 设置成
android:configChanges="orientation|screenSize"
然后,再看看看横竖屏切换时,Activity的生命周期变化:
11-07 23:18:17.104 ......MainActivity: onCreate
11-07 23:18:17.104 ......MainActivity: onResume()
11-07 23:18:21.704 ......MainActivity: onConfigurationChanged:2
11-07 23:18:26.134 ......MainActivity: onConfigurationChanged:1
11-07 23:18:28.884 ......MainActivity: onConfigurationChanged:2
11-07 23:18:33.184 ......MainActivity: onConfigurationChanged:1
从实践的数据(机型:Mi3Cmiui7)由此看见,Activity并没有发生,不需要那么麻烦手动保存数据什么的.
没想到一个参数就搞定了.
另外,
如果是为了在发生横竖屏切换时,Ui需要重新布局,则可添加横屏竖屏的xml布局,如res/layout-land;这样Android会寻找其目录下的资源;
重要的参数再说一遍:
android:configChanges="orientation|screenSize|keyboardHidden"