Android横竖屏切换咱得知道的一些东西

       Android横竖屏切换的时候,里面有很多情况咱们在开发的时候得心里得有个底,比如:为啥有些App的某些Activity界面不会横竖屏切换呢、为啥有些App的某些Activity界面屏幕切换Activity会重启呢、为啥有些App界面Activity屏幕切换的时候Activity只是回调了onConfigurationChanged()函数呢。都是那些配置信息决定的这些变化呢,咱心里得有个底。还有在屏幕横竖屏切换的时候咱们要怎么保存和恢复状态信息呢,等等等等一些列的问题。

一、 设置屏幕显示的方向(screenOrientation)

       咱们可以根据需求来设置屏幕的方向。比如,某些游戏界面,规定只能横屏显示。再比如,我们可能为了偷懒不想去处理因为屏幕旋转而要去做一些列的操作来保证应用的正常运行,直接把所有的界面都显示竖屏。

screenOrientation设置的时候一些相关值的解释如下表所示:

描述
unspecified默认值,由系统选择显示方向,不同的设备可能会有所不同。(旋转手机,界面会跟着旋转)
landscape限制横屏方向,显示的宽比高长(相当于拿着手机顺时针旋转90度)
portrait限制竖屏方向,显示的高比宽长
reverseLandscapeAPI 9 以上才能使用,限制屏幕反向横屏(相当于拿着手机逆时针旋转90度)
reversePortraitAPI 9 以上才能使用,限制屏幕反向竖屏(相当于手机倒过来)
sensor根据传感器定位方向,旋转手机界面也会旋转(一般是上、左、右的旋转)
nosensor不由传感器确定方向。旋转设备的时候,界面不会跟着旋转。初始界面方向由系统提供
sensorLandscape横屏的旋转(正向横屏、反向横屏),不会出现竖屏的现象,根据传感器定位方向,旋转手机180度界面旋转。一般横屏游戏会使用这个属性
sensorPortrait竖屏的旋转,不会出现横屏的现象。根据传感器定位方向,旋转手机180度界面会旋转
fullSensorAPI 9 以上才能使用,可以上下左右四个方向旋转屏幕
user用户当前首选的方向(旋转设备的时候,界面也会旋转)
lockedAPI 18 以上才能使用,锁死当前屏幕的方向,不会旋转
behind跟堆栈中当前Activity下面一个Activity的方向一致(感觉这个没啥作用,因为就算和堆栈下面的一个Activity相同,但是他还是会随着手机的旋转而旋转的)
userLandscapeAPI 18 以上才能使用, 横向方向,但根据设备传感器和用户的传感器首选项,可以是正常或反向的横向方向。 如果用户锁定了基于传感器的旋转,其行为与 landscape 相同,否则,其行为与 sensorLandscape 相同
userPortraitAPI 18 以上才能使用, 纵向方向,但根据设备传感器和用户的传感器首选项,可以是正常或反向的纵向方向。 如果用户锁定了基于传感器的旋转,其行为与 portrait 相同,否则,其行为与 sensorPortrait 相同
fullUserAPI 18 以上才能使用,如果用户锁定了基于传感器的旋转,其行为与 user 相同,否则,其行为与 fullSensor 相同,允许所有 4 种可能的屏幕方向

       可以通过两种方式来设置屏幕方向:

  • 通过AndroidManifest.xml文件里面 activiy标签android:screenOrientation来设置屏幕方向(这个是最常用的方式)。比如设置一直横屏显示,不管手机怎么旋转都显示横屏。
        <activity
            android:name=".statics.StaticActivity"
            android:screenOrientation="landscape"/>
  • 在Activity对应的java文件里面通过代码设置,在onCreate函数中,在setContentView()之前通过设置setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_XXXX);来设置/改变屏幕显示的方向

二、捕获手机配置项的改变(configChanges)

       configChanges:Activity需要自己处理的配置项改变。当配置在运行时发生变化的时候,默认是Activity关闭并且重启,但是,当我们声明了这个属性,Activity就不会重启(不会调用生命周期里面的函数),而是会调用 onConfigurationChanged() 函数来使用配置项的改变。这个也是横竖屏切换里面用的最多的一个标签,当横竖屏切换的时候不想Activity重启,那这个时候这个标签就排上大用场了。

configChanges可以设置的值相关解释如下(可以同时设置多个,通过 | 隔开)

描述
mccIMSI 移动国家/地区代码 (MCC) 发生了变化 - 检测到了 SIM 并更新了 MCC
mncIMSI 移动网络代码 (MNC) 发生了变化 - 检测到了 SIM 并更新了 MNC
locale语言区域发生了变化 — 用户为文本选择了新的显示语言
touchscreen触摸屏发生了变化。(这种情况通常永远不会发生。)
keyboard键盘类型发生了变化 — 例如,用户插入了一个外置键盘
keyboardHidden键盘无障碍功能发生了变化 — 例如,用户显示了硬件键盘
navigation导航类型(轨迹球/方向键)发生了变化。(这种情况通常永远不会发生。)
screenLayout屏幕布局发生了变化 — 这可能是由激活了其他显示方式所致
fontScale字体缩放系数发生了变化 — 用户选择了新的全局字号
uiMode用户界面模式发生了变化 — 这可能是因用户将设备放入桌面/车载基座或夜间模式发生变化所致.此项为 API 级别 8 中新增配置
orientation屏幕方向发生了变化 — 用户旋转了设备
screenSize当前可用屏幕尺寸发生了变化。它表示当前可用尺寸相对于当前纵横比的变化,因此会在用户在横向与纵向之间切换时发生变化
smallestScreenSize物理屏幕尺寸发生了变化。它表示与方向无关的尺寸变化,因此只有在实际物理屏幕尺寸发生变化(如切换到外部显示器)时才会变化
layoutDirection布局方向发生了变化。例如,从从左至右 (LTR) 更改为从右至左 (RTL)。 此项为 API 级别 17 中新增配置。

  • 一般通过AndroidManifest.xml文件里面 activiy标签android:configChanges来设置捕获手机配置项的改变。
        <activity
            android:name=".statics.StaticActivity"
            android:configChanges="orientation|screenSize|keyboardHidden"/>

三、屏幕旋转生命周期

       android:configChanges设置和屏幕旋转相关的值(orientation、screenSize)的时候对Activity生命周期的影响

minSdkVersion>=13 的时候(这个是我们要重点注意的,现在minSdkVersion基本上都是大于13的了

  • 只有同时设置android:configChanges=”orientation|screenSize”的情况下(一般还会带上keyboardHidden),旋转屏幕的时候不会重新调用各个生命周期,只会执行onConfigurationChanged方法。其他情况下旋转屏幕都会重新调用一次生命周期。

minSdkVersion<13 的时候(minSdkVersion<13的情况已经很少了,基本上见不到了,我们不做过多的考虑

  • 1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。
  • 2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次。
  • 3、设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。

四、状态的保存和恢复

       状态的保存和恢复,为啥要保存状态呢,在Android系统中存在这种情况,当Activity退到后台去的时候,由于种种原因可能这个Activity会被系统给回收掉,下次进来又是一个全新的生命周期,如果没有这个状态保存和恢复的话那这样你上次退到后台去之前的那些信息没有保存,是恢复不了的(比如,播放视屏的进度呀,你之前输入的一些信息呀啥的)。状态的保存和恢复就是用来应对这一情况的。可以恢复由于特殊情况销毁的Activity之前的信息。

       在状态的保存和恢复用两个特别重要的函数:onSaveInstanceState()、onRestoreInstanceState()。当某个activity变得“容易”(退到后台)被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。

       特别要注意的是onSaveInstanceState()、onRestoreInstanceState()两个函数并不是成对出现的,这点我们也好理解onSaveInstanceState()是在activity变的容易销毁的时候才会被调用,调用之后activity还指不定有没有被销毁呢,当没有销毁的时候onRestoreInstanceState()函数是不会被调用的。所以onSaveInstanceState出现的次数肯定是大于等于onRestoreInstanceState出现的次数。

       onRestoreInstanceState()的bundle参数也会传递到onCreate()方法中,你也可以选择在onCreate方法中做状态数据恢复。

onSaveInstanceState()、onRestoreInstanceState()调用情况总结如下:
1. 当用户按下HOME键时。onSaveInstanceState调用,onRestoreInstanceState不一定调用。
2. 长按HOME键,选择运行其他的程序时。onSaveInstanceState()调用,onRestoreInstanceState()不一定调用。
3. 按下电源按键(关闭屏幕显示)时。onSaveInstanceState()调用,onRestoreInstanceState()不一定调用。
4. 屏幕方向切换时(前提是没有设置android:configChanges的情况下),例如从竖屏切换到横屏时。onSaveInstanceState()调用,onRestoreInstanceState()也会调用。

五、横竖屏切换布局文件设置

       有的需求可能要求我们在横屏、竖屏的时候加载的布局文件不相同。我们有两种方式来处理这种情况。

  • 交给系统处理,在res目录下建立layout-land(放横屏时候的布局文件)和layout-port(放竖屏时候的布局文件)目录,相应的layout文件名称不变,比如main.xml。layout-land是横屏的layout,layout-port是竖屏的layout,其他的我们就不用去处理,系统会根据屏幕的状态去不同的文件加载不同的布局文件。

  • 我们自己来判断横竖屏,自己来指定布局文件,在onCreate()或者onConfigurationChanged()通过getResources().getConfiguration().orientation得到屏幕的方向,如果根据横屏还是竖屏就可以在相应的方法中重新setContentView来载入不同的layout xml布局文件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值