在onCreate里面,你是无法获得长宽值的,始终为0,为什么会这样呢?因为View的measure过程和Activity的生命周期不是同步的。所以下面来讨论一下在Activity中获取View的高度几种方法。
1.onWindowFocusChanged()
这个方法在onResume()和onPause()也会被调用,如果onResume()和onPause()被频繁调用,那么onWindowFocusChanged()也会被频繁调用。
/**
* Called when the current {@link 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.
* ……
*/
public void onWindowFocusChanged(boolean hasFocus) {
}
2.View.post()
通过post将一个Runnable投递到消息队列尾部。等Runnable被调用的时候,View已经初始化好了。
/**
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*/
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
3.ViewTreeObserver
使用OnGlobalLayoutListener(),监听布局完成,但是会多次调用,所以要及时remove掉Listener。
final ViewTreeObserver viewTreeObserver = mView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
viewTreeObserver .removeOnLayoutChangeListener(this);
}
});
类似的还有使用OnDrawListener()和OnPreDrawListener。
4.直接使用measure()
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
mView.measure(w, h);
int height = mView.getMeasuredHeight();
int width = mView.getMeasuredWidth();
System.out.println("measure width=" + width + " height=" + height);