1. 程式人生 > >android.view.ViewTreeObserver.addOnGlobalLayoutListener

android.view.ViewTreeObserver.addOnGlobalLayoutListener

有時候需要在onCreate方法中知道某個View元件的寬度和高度等資訊,而直接呼叫View元件的getWidth()、getHeight()、getMeasuredWidth()、getMeasuredHeight()、getTop()、getLeft()等方法是無法獲取到真實值的,只會得到0。這是因為View元件佈局要在onResume回撥後完成。下面提供實現方法,onGlobalLayout回撥會在view佈局完成時自動呼叫:

類似:

// This listener is used to get the final width of the GridView and then calculate the
// number of columns and the width of each column. The width of each column is variable
// as the GridView has stretchMode=columnWidth. The column width is used to set the height
// of each view so we get nice square thumbnails.
<pre name="code" class="java">mGridView.getViewTreeObserver().addOnGlobalLayoutListener( //view 佈局完成時呼叫,每次view改變時都會呼叫
		new ViewTreeObserver.OnGlobalLayoutListener() {
			@Override
			public void onGlobalLayout() {
				if (mAdapter.getNumColumns() == 0) {
				        final int numColumns = (int) Math.floor(
						         mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
					if (numColumns > 0) {
					final int columnWidth =
							(mGridView.getWidth() / numColumns) - mImageThumbSpacing;
						mAdapter.setNumColumns(numColumns);   //設定 列數
					        mAdapter.setItemHeight(columnWidth);  //設定 高度
						getViewTreeObserver().removeGlobalOnLayoutListener(this);

					}
				}
			}
		});


在gridview佈局完成後,根據girdview的寬和高設定adapter列數和每個item高度

但是需要注意的是OnGlobalLayoutListener可能會被多次觸發,因此在得到了高度之後,要將OnGlobalLayoutListener登出掉。

除了OnGlobalLayoutListener ,ViewTreeObserver還有如下內部類:

interface ViewTreeObserver.OnGlobalFocusChangeListener 當在一個檢視樹中的焦點狀態發生改變時,所要呼叫的回撥函式的介面類 interface ViewTreeObserver.OnGlobalLayoutListener 當在一個檢視樹中全域性佈局發生改變或者檢視樹中的某個檢視的可視狀態發生改變時,所要呼叫的回撥函式的介面類 interface ViewTreeObserver.OnPreDrawListener 當一個檢視樹將要繪製時,所要呼叫的回撥函式的介面類 interface ViewTreeObserver.OnScrollChangedListener 當一個檢視樹中的一些元件發生滾動時,所要呼叫的回撥函式的介面類 interface ViewTreeObserver.OnTouchModeChangeListener 當一個檢視樹的觸控模式發生改變時,所要呼叫的回撥函式的介面類