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; } }