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状态栏微技巧,带你真正意义上的沉浸式
记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...
随机推荐
- 短路与&&和按位与&的区别
条件1&&条件2,短路与&&如果条件1为假则不判断条件2:而按位与&如果条件1为假仍旧判断条件2
- linear encoder 和 PCA
- C++ STL 一般总结
以下内容来源网上 经过整合而成(转载) 一.一般介绍 STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程序库( ...
- android VoiceRecognition 语音识别并打印到列表上
package com.example.wenandroid; import java.util.ArrayList; import java.util.List; import android.ap ...
- android setCompoundDrawables和setCompoundDrawablesWithIntrinsicBounds差别
手工设置文本与图片相对位置时.经常使用到例如以下方法: setCompoundDrawables(left, top, right, bottom) setCompoundDrawablesWithI ...
- lua的string库与强大的模式匹配
lua原生解释器对字符串的处理能力是十分有限的,强大的字符串操作能力来自于string库.lua的string函数导出在string module中.在lua5.1,同一时候也作为string类型的成 ...
- C# 类型的创建
类 类是最普通的引用类型,最简单的声明如下所示: class YourNameClass { } 更复杂的类可以拥有以下这些选项: 置于关键字class前面的:属性(attributes)与class ...
- Android基础之CountDownTimer 倒计时类
app常用的60s倒计时计时功能: private static final int TIME_LIMIT = 60; private void initView() { // 相关控件 mResen ...
- 树 -- AVL树
前言 通过之前对二叉查找树的讨论,我们知道在给定节点数目的情况下,二叉树的高度越低,查找所用时间也就越短. 在讨论红黑树的时候,我们说过红黑树并非完全"平衡"的二叉树,只是近似&q ...
- C语言的声明和定义
在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事. 下面我就简单的把他们的区别介绍如下: 变量的声明有两种情况: (1)一种 ...