理解:關(guān)于View的知識
1. View的getWidth()和getMeasuredWidth()有什么區(qū)別嗎?
getWidth是獲取控件真實(shí)的寬度旱函,在view.onlayout之后才能獲取到灾而。
getMeasuredWidth()是獲取的計(jì)算寬度榕栏,在view.onmeasure之后獲取。
會受到measure影響,而結(jié)果不同.
@ViewDebug.ExportedProperty(category = "layout")
public final int getWidth() {
return mRight - mLeft;
}
public final int getMeasuredWidth() {
return mMeasuredWidth & MEASURED_SIZE_MASK;
}
2.如何在OnCreate中拿到View的寬度和高度?
- view.post(runnable) 使用 主線程的handle發(fā)送message
能保證獲取的原因是因?yàn)椋?br> oncreate的時(shí)候mAttachInfo還為空仑荐,那些Runnable并沒有馬上被執(zhí)行撑毛,而是保存到RunQueue里面。
執(zhí)行的接口就是RunQueue.executeActions腺办,其內(nèi)部也看到是調(diào)用Handler執(zhí)行的,RunQueue.executeActions()這個(gè)接口在整個(gè)ViewRootImpl里只有一個(gè)地方調(diào)用糟描,就是在performTraversals(),但是由于是發(fā)送的延時(shí)消息而且executeActions其實(shí)是在onlayut之前調(diào)用,不太好說(屏幕是黑屏?xí)r,OnCreate獲取的還是0)
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
- ViewTreeObserver.addOnPreDrawListener / ViewTreeObserver.addOnGlobalLayoutListener
在draw之前獲取監(jiān)聽(屏幕是黑屏?xí)r,OnCreate獲取的還是0)
ViewTreeObserver.addOnGlobalLayoutListener
可見性發(fā)送變化時(shí)(這個(gè)更適合)
final ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
Log.e("TAG","onPreDraw:"+textView.getWidth());
textView.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e("TAG","onGlobalLayout:"+textView.getWidth());
textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
- textView.addOnLayoutChangeListener
在view的layout的時(shí)候
if (li != null && li.mOnLayoutChangeListeners != null) {
ArrayList<OnLayoutChangeListener> listenersCopy =
(ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}