android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

背景:之前有过两篇写activity的博客android之activity的生命周期详解:详细介绍了activity的整个生命周期、各状态间的转换和返回桌面时保存activity的状态android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用本篇博客会牵扯到里面的内容,如果你都

大家好,又见面了,我是全栈君。

背景:之前有过两篇写activity的博客

android之activity的生命周期详解:详细介绍了activity的整个生命周期、各状态间的转换和返回桌面时保存activity的状态

android之activity中onSaveInstanceState和onRestoreInstanceState的触发时机:介绍了activity中这两个方法的触发时机和作用

本篇博客会牵扯到里面的内容,如果你都有所了解可以直接往下看,如果不了解可以进去回忆下。

问题:在做应用的退出对话框时,发现如果对话框弹出,然后把手机横竖屏切换一下,对话框就消失了。知道activity在横竖屏切换时会走一些生命周期,就误以为是在onPause和onResume的时候没有把对话框恢复出来,

首先想到就是设一个全局变量isDialogShow用来保存对话框是否显示,在onPause中检查下如果显示了,就把isDialogShow设置为true,然后在onResume中判断下isDialogShow的值,如果为true,则把对话框在显示出来。

以为这样就解决了,运行发现不对,对话框还是不显示。

然后debug发现,每次进入onResume的时候,isDialogShow都是false,也就是说每次isDialogShow都被重新初始化了。

这时候才突然意识到,横竖屏切换的时候生命周期可能不是我想的那样。

就借着这个机会去总结一下activity横竖屏切换时如何保存状态以及自适应布局。

解决方案对于这个问题,有三种方案

1⃣️顺应activity的生命周期,保存然后恢复状态,onCreate中动态适应布局。

2⃣️在AndroidManifest.xml中设置,不让activity重走生命周期从而保存状态,通过onConfigurationChanged自适应布局或者setRequestedOrientation手动设置横竖屏,此时activity的生命周期是不会重走的

3⃣️禁止activity的横竖屏转换,状态和布局保持原样。

方案一

首先把activity的每个方法打印出来。

启动应用(此时是竖屏):

android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

切换为横屏:

       android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

里面的数字是加的一个全局变量(初始化为0,每进入一次onPause自动加1),用来看数值的变化,可见在onPause的时候还是1,等切换完成再回来的时候就成了0了。

也很容易理解,activity相当于完全重新做了一次初始化,完整走了一遍生命周期。

同时也注意到,切换为横屏的时候多了onSaveInstanceState和onRestoreInstanceState方法,上面第二篇博客里面说到的,activity在有“被销毁的可能”时,就会调用onSaveInstanceState方法,给你一个机会去保存activity中的数据,之后横竖屏切换时activity确实在“未经你许可的情况下被销毁了”,所以系统又会调用onRestoreInstanceState方法,让你把之前保存的数据恢复。

所以这样就明白了为什么我的对话框切换横竖屏之后不出来,而且用来记录的isDialogShow的值会被重置,如此解决方案也有了。

onSaveInstanceState方法中保存isDialogShow的值,然后在onRestoreInstanceState方法中取回isDialogShow 的值,去判断该不该显示对话框就可以了。

那么如何自适应布局呢,像xml之类的资源,只要建两套就可以了,横屏资源放在res/layout-land里面,竖屏资源放在res/layout-port文件夹里面,资源名字都一样即可,系统会自己去找。

也可以通过以下方法获取目前横竖屏状态分别实现一些资源的加载。

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
 //do something
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
 //do something
}

以上就完成了在activity的完整生命周期里面保存状态以及自适应资源。



方案二

在说方案二的时候要提一下,既然可以避免activity重新走生命周期,为什么还要设计这个横竖屏切换的时候去完整的重新走一遍生命周期呢?

因为既然手机切换了横竖屏,比如从竖屏切换为横屏了,那么原来竖屏的layout,drawable等资源可能无法适应横屏模式,设计完善的应用一般是会有两套资源来适配横竖屏模式的,所以在切换后重启activity,在新的创建过程中就会自

动使用横屏的资源,实现了动态适应。

方案二只需要在manifest文件中的activity标签下加如下代码

android:configChanges=”orientation”

这段代码的含义是向系统说明,这个activity的orientation发生变化时,我不需要你去自适应,我自己会在onConfigurationChanged方法中做处理或者说我自己完成横竖屏切换的适应,即告诉activity不要重新走生命周期,放着我来。

加上这个代码声明之后,重新运行会发现,activity的生命周期没有出现,只出现了一个方法就是

android之activity横竖屏切换时的生命周期以及横竖屏切换时的资源适配方案

那么切换过程中你要如何处理就是你自己的事情了,状态无需保存,都还是原来的,如果要做一些切换的话,可以通过如下代码获取到当前的横竖屏状态,然后自己操作。

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
 // do something
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
 // do something
}

如果只是加下面这个的话,你会发现activity还是会走完整的生命周期,onConfigurationChanged方法压根不会执行

android:configChanges=”orientation”

这是因为从Android 3.2(API 13)开始,横竖屏切换时不仅orientation会发生变化,screenSize也会跟着发生变化,所以要改成下面这样。
android:configChanges=”orientation|screenSize”
告诉activity,不管是orientation变化还是screenSize变化,都不要重新初始化,都通过onConfigurationChanged让我自己操作。

以上就是不让activity重新初始化,而是自己完成横竖屏切换的自适应操作。

方案三

最简单最粗暴,禁止横竖屏转换,直接固定为横屏或者竖屏。

可以在配置Activity的地方进行如下的配置

android:screenOrientation="portrait"
android:screenOrientation="landscape" 

或者在onCreate里面

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
or
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

这样就可以保证是竖屏总是竖屏了,或者横屏总是横屏。

以上,就不涉及状态保存和布局适应了,不管横屏竖屏一切如初。

参考:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1106/516.html

http://blog.csdn.net/aliang775/article/details/8561075

作者:jason0539

微博:http://weibo.com/2553717707

博客:http://blog.csdn.net/jason0539(转载请说明出处)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121334.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • URL转码与解码

    URL转码与解码classUrlUtil publicstatic String args throwsUnsupp Stringres getURLEncode books 测试分享 page 依赖的第三方系统分享 System out println res res getURLDecode res Syst

    2025年8月8日
    3
  • SpringBoot❤SpringClould常用注解史诗级汇总[通俗易懂]

    SpringBoot❤SpringClould常用注解史诗级汇总[通俗易懂]什么是注解?什什么是注解Java注解是附加在代码中的⼀一些元信息,⽤用于⼀一些⼯工具在编译、运⾏行行时进⾏行行解析和使⽤用,起到说明、配置的功能注解本质上继承Annotation接⼝口,我们可以通过反射获取注解的相关信息,从⽽而做些逻辑操作springboot⾥里里⾯面⼤大量量使⽤用了了注解,@Controller、@RestController、@Service、@Autowire等一、SpringBoot注解1.1.@SpringBootApplication包含@Confi

    2022年7月20日
    14
  • Fiddler 实现手机抓包详解

    Fiddler 实现手机抓包详解1、Fiddler简介Fiddler是一款强大的抓包工具,原理是以web代理服务器的形式进行工作的:2、Fiddler配置2.1允许监听httpsFiddler如果抓取https协议会话需要进一步配置,在Tools->Options菜单下,选择HTTPS标签并配置如下:2.2允许远程连接手机抓取需要配置远程连接,在Tools->Options菜单下,选择Connections标签并配置如下:监听端口8888并允许远程连接防火墙需要开放

    2022年6月29日
    37
  • Discuz论坛搬家教程

    Discuz论坛搬家教程搬家之前最好先备份1.备份数据库(管理中心->站长->数据库)2.复制整个bbs工程(ps:需要搬家的论坛,以下均用bbs代替)到新的服务器上;3.进入新下载的Discuz(ps:上官方下载一个和你以前论坛一样编码的最新版下来)安装目录upload/install里复制index.php文件到bbs/install目录下;(新Discuz安装包下载…

    2022年7月25日
    15
  • 空间统计:Moran’s I(莫兰指数)

    空间统计:Moran’s I(莫兰指数)前两天聊了空间统计学里面的两个经典概念,今天来说说第一篇文章留下的大坑:Moran’sI。首先,Moran’sI这个东西,官方叫做:莫兰指数,是澳大利亚统计学家帕特里克·阿尔弗雷德·皮尔斯·莫兰(PatrickAlfredPierceMoran)(好长的名字,不过一般都简称为:帕克·莫兰,就是下图这位中年帅哥了),在1950年提出的。这一年,朝鲜战争爆发。莫兰同学1917…

    2022年6月25日
    86
  • 图片url地址的生成获取方法

    图片url地址的生成获取方法图片url地址的生成获取方法  在写博客插入图片时,许多时候需要提供图片的url地址。作为菜鸡的我,自然是一脸懵逼。那么什么是所谓的url地址呢?又该如何获取图片的url地址呢?  首先来看一下度娘对url地址的解释:url是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的url,它包含的信息指出文件的位置以及浏览器应该怎么处理它。  简单来说,url地址是是用来定位、访问网上资源用的。常见的网址也属于url地

    2022年9月22日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号