本文主要讨论以下几个问题
- 横竖屏切换触发哪些生命周期?
- Activity销毁时如何保存数据?
- 如何保证横竖屏切换时不销毁Activity
- 横竖屏切换对fragment的影响
android:screenOrientation
screenOrientation设置 activity在设备上的显示方向的,只能设置一个值
值 | 描述 |
---|---|
unspecified | 默认值。系统自动选择屏幕方向 |
behind | 跟activity堆栈中的下面一个activity的方向一致 |
landscape | 横屏方向,显示的宽比高长 |
portrait | 竖屏方向,显示的高比宽长 |
sensor | 由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换 |
nosensor | 忽略物理方向传感器,这样就不会随着用户旋转设备而横竖屏切换了("unspecified"设置除外) |
user | 用户当前首选的方向 |
sensorLandscape | API 9 以上,横屏,但是可以根据 物理方向传感器来切换正反向横屏 |
sensorPortrait | API 9 以上,竖屏,但是可以根据 物理方向传感器来切换正反向竖屏 |
fullSensor | API 9 以上,上下左右四个方向,由物理方向传感器决定 |
locked | API 18 以上,锁死当前屏幕的方向 |
只设置screenOrientation切换横竖屏,生命周期变化如下
2020-11-16 13:35:36.876 29849-29849/com.example.kotlinstart E/aaa: onCreate: [onCreate]
2020-11-16 13:35:36.919 29849-29849/com.example.kotlinstart E/aaa: onStart: [onStart]
2020-11-16 13:35:36.921 29849-29849/com.example.kotlinstart E/aaa: onResume: [onResume]
2020-11-16 13:35:39.349 29849-29849/com.example.kotlinstart E/aaa: onPause: [onPause]
2020-11-16 13:35:39.356 29849-29849/com.example.kotlinstart E/aaa: onStop: [onStop]
2020-11-16 13:35:39.360 29849-29849/com.example.kotlinstart E/aaa: onSaveInstanceState: [onSaveInstanceState]
2020-11-16 13:35:39.361 29849-29849/com.example.kotlinstart E/aaa: onDestroy: [onDestroy]
2020-11-16 13:35:39.432 29849-29849/com.example.kotlinstart E/aaa: onCreate: [onCreate]
2020-11-16 13:35:39.446 29849-29849/com.example.kotlinstart E/aaa: onStart: [onStart]
2020-11-16 13:35:39.447 29849-29849/com.example.kotlinstart E/aaa: onRestoreInstanceState: [onRestoreInstanceState]
2020-11-16 13:35:39.448 29849-29849/com.example.kotlinstart E/aaa: onResume: [onResume]
只设置screenOrientation切换横竖屏会销毁Activity并重新创建,需要调用onSaveInstanceState保存数据,实现如下:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Log.e(TAG, "onSaveInstanceState: [onSaveInstanceState]" )
outState.putString("content", mBinding.et.text.toString())
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
Log.e(TAG, "onRestoreInstanceState: [onRestoreInstanceState]")
mBinding.et.setText(savedInstanceState.getString("content"))
}
android:configChanges
用来设置 activity配置改变(不仅仅是屏幕方向,还有语言、地区等等)的集合。当一个配置改变在运行中发生时,activity默认情况下会先销毁然后重新创建。但是,如果通过这个属性声明了某个配置后,将可以避免上面的情况,而是依然运行,并回调 onConfigurationChanged方法。该属性可以设置多个值
值 | 描述 |
---|---|
keyboardHidden | 键盘的可访问性发生变化 |
screenLayout | 屏幕布局发生变化——这个会导致显示不同的Activity |
orientation | 屏幕方向发生变化——用户旋转了屏幕。注意:如果应用程序的目标API级别是13或更高(通过属性minSdkVersion和属性targetSdkVersion声明),你也需要声明配置项screenSize,因为这将在设备选择肖像和屏幕方向时发生改变 |
screenSize | 当前可用屏幕大小发生变化 |
详情请看官方文档
android:configChanges="orientation|screenSize"
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
Log.e(TAG, "onConfigurationChanged: [onConfigurationChanged = ],${newConfig.orientation} ")
}
2020-11-16 13:57:19.617 31464-31464/com.example.kotlinstart E/aaa: onCreate: [onCreate]
2020-11-16 13:57:19.660 31464-31464/com.example.kotlinstart E/aaa: onStart: [onStart]
2020-11-16 13:57:19.662 31464-31464/com.example.kotlinstart E/aaa: onResume: [onResume]
2020-11-16 13:57:22.443 31464-31464/com.example.kotlinstart E/aaa: onConfigurationChanged: [onConfigurationChanged = ],2
2020-11-16 13:57:22.443 31464-31464/com.example.kotlinstart E/aaa: onConfigurationChanged: [onConfigurationChanged = ],1
使用configChanges后Activity没有销毁,没有生命周期调用,只有onConfigurationChanged回调,这儿也可以做很多事情
相关问题
1.手动切换横竖屏
mBinding.btn.setOnClickListener {
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
//切换竖屏
this@TestActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}else{
//切换横屏
this@TestActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
}
2.切换横竖屏时的布局切换
在资源目录res 中添加了 layout-land(横向布局文件夹) 和 layout-port (竖想布局文件夹),重启Activity模式的横竖屏切换,系统会自动帮我们显示正确方向的布局UI,如果是手动切换则需要如下操作
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
Log.e(TAG, "onConfigurationChanged: [onConfigurationChanged = ],${newConfig.orientation} ")
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
//切换竖屏
setContentView(R.layout.activity_test)
}else{
//切换横屏
setContentView(R.layout.activity_test)
}
}
3.切换横竖屏对fragment的影响
fragment会随着Activity的销毁而销毁
设置configChanges后不会调用其生命周期函数,会调用fragment的onConfigurationChanged函数,如下日志:
2020-11-16 14:22:47.000 1416-1416/com.example.kotlinstart E/aaa: onCreate: [onCreate]
2020-11-16 14:22:47.078 1416-1416/com.example.kotlinstart E/TestFragment: onCreate: [onCreate]
2020-11-16 14:22:47.081 1416-1416/com.example.kotlinstart E/TestFragment: onCreateView: [onCreateView]
2020-11-16 14:22:47.087 1416-1416/com.example.kotlinstart E/aaa: onStart: [onStart]
2020-11-16 14:22:47.091 1416-1416/com.example.kotlinstart E/aaa: onResume: [onResume]
2020-11-16 14:22:47.091 1416-1416/com.example.kotlinstart E/TestFragment: onResume:
2020-11-16 14:24:06.761 1416-1416/com.example.kotlinstart E/TestFragment: onConfigurationChanged:
2020-11-16 14:24:06.762 1416-1416/com.example.kotlinstart E/aaa: onConfigurationChanged: [onConfigurationChanged = ],2