天天看點

android invalidate()與requestLayout()差別

invalidate與requestLayout的差別

    • invalidate()與requestLayout()是view中的方法
    • invalidate()
    • requestLayout()

invalidate()與requestLayout()是view中的方法

代碼添加一個自定義view,view顯示在螢幕上的工作流程:

new CustomView->ViewGroup.addView(CustomView)->measure->onMeasure->layout->onLayout->draw->onDraw(繪制自己)->dispatchDraw(繪制子視圖)

invalidate()

/**
     * Invalidate the whole view. If the view is visible,
     * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
     * the future.
     * <p>
     * This must be called from a UI thread. To call from a non-UI thread, call
     * {@link #postInvalidate()}.
     */
    public void invalidate() {
        invalidate(true);
    }
           

這個方法是用來重新整理整個視圖的,當視圖的内容,可見性發生變化,onDraw(Canvas canvas)方法會被調用。

注意:

1.調用invalidate()方法不會導緻measure和layout方法被調用,具體原因可看源碼。

2.如果視圖是viewGroup,其子view的内容或者位置變化,調用invalidate()方法,因為對viewGroup而言,其大小和位置并沒有發生變化。

3.invalidate()方法必須在UI線程中調用,如果想在非UI線程中調用,則使用postInvalidate()

requestLayout()

/**
     * Call this when something has changed which has invalidated the
     * layout of this view. This will schedule a layout pass of the view
     * tree. This should not be called while the view hierarchy is currently in a layout
     * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
     * end of the current layout pass (and then layout will run again) or after the current
     * frame is drawn and the next layout occurs.
     *
     * <p>Subclasses which override this method should call the superclass method to
     * handle possible request-during-layout errors correctly.</p>
     */
    @CallSuper
    public void requestLayout() {
    ...
    }
           

requestLayout()是在view的布局發生變化時調用,布局的變化包含位置,大小。

注意:

1.這個方法不能在正在布局的時候調用

2.調用這個方法,會導緻布局重繪,調用measure,layout,draw的過程。