Activity之onWindowFocusChanged
public void onWindowFocusChanged (boolean hasFocus)
参数hasFocus: the window of this activity has focus.
是指activity是否获取或失去了focus,获得到了该参数为true,否则为false。一般是进入或恢复Actiity时为true,Actvity销毁或者退到后台则为false。
Called when the current Window of the activity gains or loses focus. This is the best indicator of whether this activity is visible to the user. The default implementation clears the key tracking state, so should always be called. Note that this provides information about global focus state, which is managed independently of activity lifecycles. As such, while focus changes will generally have some relation to lifecycle changes (an activity that is stopped will not generally get window focus), you should not rely on any particular order between the callbacks here and those in the other lifecycle methods such as onResume(). As a general rule, however, a resumed activity will have window focus... unless it has displayed other dialogs or popups that take input focus, in which case the activity itself will not have focus when the other windows have it. Likewise, the system may display system-level windows (such as the status bar notification panel or a system alert) which will temporarily take window input focus without pausing the foreground activity.
上面的官方的注解,大意是这个方法可以真正表示activity对用户的可见。focus状态处理是和activity的生命周期独立的,但是有有相关性,比如一个停止了的activity一般不会获取focus,也不依赖既定的声明周期的回调函数如onResume()来确保这个focus的获取。
一般一个resumed的activity会获得焦点,除非它展示的dialog或者弹出框截取了focus,这时候activity只有在其他窗口释放focus后才会获取。类似的,系统也会优先显示系统的窗口比附状态栏通知或者系统alert,这些都会暂时取走焦点但是不会停止前台activity的状态。
啰嗦了这么多,其实就是想说在这个监听的函数里能做很多事情。
1.它的调用表示activity中的所有控件都已经准备好,可以进行UI交互了,这在其它生命周期函数里都无法判断,常见的就是测量控件,获取控件的宽高。
在onCreate()中使用一个view的getWidth() getHeight() 方法来获取该view的宽和高,返回的值常常。解决该问题的方法有很多,主要就是延后调用这些方法。比如会使用主线程的postDelay的方法延迟获取,会得到如果这个view的长宽。因为如果过早的调用View的getWidth等方法,也就是说在这个view被加入到rootview之前就调用了返回的值自然为0。但是延迟的方法总觉得时间控制上不那么可靠。
但可以在onWindowFocusChanged()里面调用这些方法来测量控件的size,是可以获取到View的宽高的。还可以进行一些Activty进入时的控件的状态默认设置。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
// Activity失去焦点时不获取 update by bianmaoran on v2.3.1
return;
}
// 在view绘制完毕后才能获取到坐标
// 上传照片显示后重新获取坐标
mBreakfastLayout.getLocationOnScreen(posBreakfast);
mLunchLayout.getLocationOnScreen(posLunch);
mDinnerLayout.getLocationOnScreen(posDinner);
mOtherLayout.getLocationOnScreen(posOther);
mDietaryRg.setOnCheckedChangeListener(new CheckedListener());
// 设置RadioButton的初始选中状态
switch (mealType) {
case 1:
mDietaryRg.check(R.id.rb_breakfast);
break;
case 2:
mDietaryRg.check(R.id.rb_lunch);
break;
case 3:
mDietaryRg.check(R.id.rb_dinner);
break;
case 4:
mDietaryRg.check(R.id.rb_other);
break;
default:
break;
}
}
2.温习一下Activity的生命周期(参考一篇描述详尽的文章onWindowFocusChanged重要作用 and Activity生命周期)
1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
<所以一些页面的数据在被杀后因为重新onCreate肯定会有丢失,这里的恢复和保存要有相应的处理方式,特别是与登录状态有关的数据,以后会讨论到>
7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
1.onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前Activity。以上几种情况都会调用onWindowFocusChanged,并且当Activity被创建时是在onResume之后被调用,当Activity被覆盖或者退居后台或者当前Activity退出时,它是在onPause之后被调用。
这个方法在某种场合下还是很有用的,例如程序启动时想要获取视特定视图组件的尺寸大小,在onCreate中可能无法取到,因为窗口Window对象还没创建完成,这个时候我们就需要在onWindowFocusChanged里获取。
2.onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用;(2)在用户改变屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。第一种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。onSaveInstanceState的调用顺序是在onPause之前。
3.onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此Activity,此方法会被调用;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。onRestoreInstanceState的调用顺序是在onStart之后。
当从后台会到前台时,系统先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,Activity又进入了运行状态。
参考文章:
onWindowFocusChanged重要作用 and Activity生命周期
Activity之onWindowFocusChanged的更多相关文章
- android activity中监听View测量完成的4种方式
在开发中经常碰到需要在activity初始化完成后获得控件大小的情况. 但是这个操作我们不能在oncreate.onresume等生命周期方法中调用,因为我们不知道何时view才能初始化完成 为此,特 ...
- Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?
在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ? @Override protected void onCreate(Bundle savedInstanc ...
- Android 开发 Activity里获取View的宽度和高度 转载
原文地址:https://blog.csdn.net/chenbaige/article/details/77991594 前言: 可能很多情况下,我们都会有在activity中获取view 的尺寸大 ...
- Activity启动过程中获取组件宽高的五种方式
第一种:(重写Activity的onWindowFocusChanged方法) /** * 重写Acitivty的onWindowFocusChanged方法 */ @Override public ...
- 在渲染前获取 View 的宽高
在渲染前获取 View 的宽高 这是一个比较有意义的问题,或者说有难度的问题,问题的背景为:有时候我们需要在view渲染前去获取其宽高,典型的情形是,我们想在onCreate.onStart.onRe ...
- (转)ViewPager,ScrollView 嵌套ViewPager滑动冲突解决
ViewPager,ScrollView 嵌套ViewPager滑动冲突解决 本篇主要讲解一下几个问题 粗略地介绍一下View的事件分发机制 解决事件滑动冲突的思路及方法 ScrollView 里面嵌 ...
- 安卓开发 想要获取某个View的高度(我是在做滚动浮层的时候用到的)
1.activity中有个onWindowFocusChanged()方法,可以获取控件的大小,别的地方可能会调用过早导致获取不到实际的大小 @Override public void onWindo ...
- Android坐标系统
1 背景 去年有很多人私信告诉我让说说自定义控件,其实通观网络上的很多博客都在讲各种自定义控件,但是大多数都是授之以鱼,却很少有较为系统性授之于渔的文章,同时由于自己也迟迟没有时间规划这一系列文章, ...
- Android状态栏微技巧,带你真正意义上的沉浸式
记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...
随机推荐
- 克拉夫斯曼高端定制 刘霞---【YBC中国国际青年创业计划】
克拉夫斯曼高端定制 刘霞---[YBC中国国际青年创业计划] 克拉夫斯曼高端定制 刘霞
- 关于 viewport meta
典型代码 <meta name="viewport" content="width=device-width, initial-scale=1.0"> ...
- Quartz.NET 2.0 作业调度框架使用
Quartz.NET是一个开源的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性而不 ...
- 第六章SignalR的服务器广播
第六章SignalR的服务器广播 1.概述: VS可以通过 Microsoft.AspNet.SignalR.Sample NuGet包来安装一个简单的模拟股票行情应用.在本教程的第一部分,您将从头开 ...
- 用SQL脚本移除视图中存在的机器名
用SQL脚本移除视图中存在的机器名 例子: msccdr.cdr.DimRMAReturnMethod CREATE VIEW CDR.DimRMAReturnMethod ( ReturnMetho ...
- HighlightingSystem插件使用(边缘发光)
插件链接: http://pan.baidu.com/s/1dFwkaTr 密码: nw2c 导入Unity里面可能会报错,不过没关系,直接注释掉就可以了,我用的是Unity5.1的版本 可以看到如下 ...
- Python核心编程读笔 13:执行环境
第14章 执行环境 一.可调用对象 python有四种可调用对象:函数.方法.类.一些类的实例 1 函数 (1)内建函数(BIF) BIF是用c/c++写的,编译后放入python解释器,然后把它们 ...
- Manacher 算法
Manacher算法用于求回文子串,它的复杂度为O(n). 这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了.在相邻的两个字符之间加进一个分隔符 '#' ,串的首尾也要加. 原 ...
- php7 install memcached extension
#download source code package from git $ git clone https://github.com/php-memcached-dev/php-memcache ...
- C语言学习——C和Java语言不同点
Java中有boolean数据类型,”真“为true,”假“为false.而且在if()括号里只能放boolean类型的值. C的基本数据类型和Java的基本一致,但C多了指针类型.指针是C语言的重点 ...