1. 程式人生 > >Android Activity和Fragment如何獲取控制元件的高度和寬度

Android Activity和Fragment如何獲取控制元件的高度和寬度

在 Activity的onCreate() 中呼叫某個按鈕的 myButton.getHeight(),得到的結果永遠是0

onCreate(): Height=0
onStart(): Height=0
onPostCreate(): Height=0
onResume(): Height=0
onPostResume(): Height=0
onAttachedToWindow(): Height=0
onWindowsFocusChanged(): Height=1845
可以看到,直到 onWinodwsFocusChanged() 函式被呼叫,我們才能得到正確的控制元件尺寸。其他 Hook 函式,包括在官方文件中,描述為在 Activity 完全啟動後才呼叫的 onPostCreate() 和 onPostResume() 函式,均不能得到正確的結果。但是該方法只適用於Activity

對於Fragment可以採用下面的方法:

1. 使用 ViewTreeObserver 提供的 Hook 方法。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
    myButton = (Button) findViewById(R.id.button1);
    
    // 向 ViewTreeObserver 註冊方法,以獲取控制元件尺寸
    ViewTreeObserver vto = myButton.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        public void onGlobalLayout() {
            int h = myButton.getHeight();
            Log.i(TAG, "Height=" + h); // 得到正確結果
 
            // 成功呼叫一次後,移除 Hook 方法,防止被反覆呼叫
            // removeGlobalOnLayoutListener() 方法在 API 16 後不再使用
            // 使用新方法 removeOnGlobalLayoutListener() 代替
            myButton.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } 
    });
    
    // ...
}
該方法在 onGlobalLayout() 方法將在控制元件完成繪製後呼叫,因而可以得到正確地結果。該方法在 Fragment 中,也可以使用。

2. 使用 View 的 post() 方法
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
    myButton = (Button) findViewById(R.id.button1);
    
    // 使用myButton 的 post() 方法
    myButton.post(new Runnable() {
        @Override
        public void run() {
            int h = myButton.getHeight();
            Log.i(TAG, "Height=" + h); // 得到正確結果
        }
    });
    
    // ...
}