2011-09-22 91 views
5

我創建了一個擴展ViewGroup的自定義佈局。一切工作正常,我得到了預期的佈局。ViewGroup完成充氣事件

我想動態地更改佈局中的元素。然而,這不起作用,因爲我在onCreate中調用它,直到那時整個佈局實際上(繪製)膨脹到屏幕上,因此沒有實際大小。

是否有任何事件可以用來找出佈局的通貨膨脹何時完成?我嘗試過使用FinishInflate,但這不起作用,因爲Viewgroup有多個視圖,並且這將被多次調用。

我想在自定義佈局類中創建一個接口,但不知道何時觸發它?

回答

20

如果我正確地理解您的需求,一個OnGlobalLayoutListener可能給你什麼你需要。

View myView=findViewById(R.id.myView); 
    myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       //At this point the layout is complete and the 
       //dimensions of myView and any child views are known. 
      } 
     }); 
+0

我一直在使用它來調整文本視圖中的文本大小,從來不知道這也可以用於ViewGroup。謝謝您的幫助! – PravinCG

2

通常在創建延伸爲ViewViewGroup的自定義佈局時,您必須覆蓋protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)protected void onLayout(boolean changed, int left, int top, int right, int bottom)。這些在通貨膨脹過程中被調用以獲得與視圖有關的大小和位置信息。此外,如果您正在延伸ViewGroup,則您需要在其中包含的每個子視圖上致電measure(int widthMeasureSpec, int heightMeasureSpec)layout(int l, int t, int r, int b)。 (measure()在onMeasure()中調用,layout()在onLayout()中調用)。

無論如何,在onMeasure(),你通常會做這樣的事情。

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    // Gather this view's specs that were passed to it 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
    int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

    int chosenWidth = DEFAULT_WIDTH; 
    int chosenHeight = DEFAULT_HEIGHT; 
    if(widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) 
     chosenWidth = widthSize; 
    if(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.EXACTLY) 
     chosenHeight = heightSize; 

    setMeasuredDimension(chosenWidth, chosenHeight); 

    *** NOW YOU KNOW THE DIMENSIONS OF THE LAYOUT *** 
} 

onLayout()你查看的實際像素座標,這樣你可以得到的物理尺寸,像這樣:

@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
{ 
    // Android coordinate system starts from the top-left 
    int width = right - left; 
    int height = bottom - top; 
} 
+0

感謝您的回覆。我已經完成了所有你已經規定了我的查詢,因爲這個值將是動態的,我如何從活動傳遞數據,更重要的是何時(事件)? – PravinCG

+1

好的。我以爲你在視圖中動態地改變了視圖。如果是這樣的話,你可以使用這兩種方法找出你的座標(甚至在視圖之前)。另一種選擇可能是使用'Activity'的一部分'onWindowFocusChanged()'。根據文檔「當活動的當前窗口獲得或失去焦點時調用」。這是此活動是否對用戶可見的最佳指標。默認實現會清除密鑰跟蹤狀態,因此應該始終調用。 「我用它來確定窗戶何時被看到(因此膨脹)。 – DeeV

+0

+1,謝謝你的迴應。上述方法雖然可能在某些情況下可行,但並不是可靠的方法。 – PravinCG