Android 横竖屏切换及相关问题

本文主要讨论以下几个问题

  1. 横竖屏切换触发哪些生命周期?
  2. Activity销毁时如何保存数据?
  3. 如何保证横竖屏切换时不销毁Activity
  4. 横竖屏切换对fragment的影响

android:screenOrientation

screenOrientation设置 activity在设备上的显示方向的,只能设置一个值

描述
unspecified默认值。系统自动选择屏幕方向
behind跟activity堆栈中的下面一个activity的方向一致
landscape横屏方向,显示的宽比高长
portrait竖屏方向,显示的高比宽长
sensor由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换
nosensor忽略物理方向传感器,这样就不会随着用户旋转设备而横竖屏切换了("unspecified"设置除外)
user用户当前首选的方向
sensorLandscapeAPI 9 以上,横屏,但是可以根据 物理方向传感器来切换正反向横屏
sensorPortraitAPI 9 以上,竖屏,但是可以根据 物理方向传感器来切换正反向竖屏
fullSensorAPI 9 以上,上下左右四个方向,由物理方向传感器决定
lockedAPI 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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值