理解:关于View的知识
1. View的getWidth()和getMeasuredWidth()有什么区别吗?
getWidth是获取控件真实的宽度,在view.onlayout之后才能获取到。
getMeasuredWidth()是获取的计算宽度,在view.onmeasure之后获取。
会受到measure影响,而结果不同.
@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发送message
能保证获取的原因是因为:
oncreate的时候mAttachInfo还为空,那些Runnable并没有马上被执行,而是保存到RunQueue里面。
执行的接口就是RunQueue.executeActions,其内部也看到是调用Handler执行的,RunQueue.executeActions()这个接口在整个ViewRootImpl里只有一个地方调用,就是在performTraversals(),但是由于是发送的延时消息而且executeActions其实是在onlayut之前调用,不太好说(屏幕是黑屏时,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之前获取监听(屏幕是黑屏时,OnCreate获取的还是0)
ViewTreeObserver.addOnGlobalLayoutListener
可见性发送变化时(这个更适合)
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的时候
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);
}
}