第五周 关于View的知识

理解:关于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的宽度和高度?

  1. 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;
    }
  1. 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);
            }
        });
  1. textView.addOnLayoutChangeListener

在view的layout的时候

            if (li != null && li.mOnLayoutChangeListeners != null) {
                ArrayList listenersCopy =
                        (ArrayList)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);
                }
            }

你可能感兴趣的:(第五周 关于View的知识)