2011-10-23 46 views
4

要移動視圖,我調用setX,setY和其他一些函數來設置寬度和高度,並在每個函數結束時調用invalidate或requestLayout。因此,每個用戶事件都會調用invalidate和requestLayout多次。這是否會觸發每個用戶事件的多個佈局/繪圖?調用requestLayout或多次失效會傷害性能嗎?

回答

1

是的,它的確如此。每次你調用無效時,視圖本身都會重繪!

1

每次你調用invalidate,視圖本身都會重繪!

這在技術上並非如此。 invalidate將在視圖上設置一個標誌,使其符合重繪要求。

一個簡單的測試是在onDraw中放入一條日誌語句,然後在循環中調用invalidate。你會看到每個迭代都沒有日誌。

3

當然not.We可以在ViewRootImpl

void invalidate() { 
    mDirty.set(0, 0, mWidth, mHeight); 
    if (!mWillDrawSoon) { 
     scheduleTraversals(); 
    } 
    } 

無效設置髒區看到代碼,並調用scheduleTraversals,它會調用doTraversal。

void doTraversal() { 
    if (mTraversalScheduled) { 
     mTraversalScheduled = false; 
     mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); 

     if (mProfile) { 
      Debug.startMethodTracing("ViewAncestor"); 
     } 

     performTraversals(); 

     if (mProfile) { 
      Debug.stopMethodTracing(); 
      mProfile = false; 
     } 
    } 
} 

,我們可以看到在代碼mTraversalScheduled標誌,如果我們scheduleding旅遊,使無效的事件triggerd,mTraversalScheduled是doTraversal假的,所以該方法將直接返回。 因此,不是每個稱爲performTravel的無效事件,也不是每個稱爲重繪的無效事件