獲取 View 的layout, 用OnGlobalLayoutListener , OnLayoutChangeListener ,view.post(new Runnable()
有時需要獲取某個 View 的layout, 或寬度,高度. 但如果太早呼叫只會得到null
因此通常會有以下三種方法
1.使用 ViewTreeObserver. OnGlobalLayoutListener 監聽事件:
在layout發生改變前加入該事件,會被多次呼叫,因此在獲取到layout後 remove 該事件。
view.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
view.getWidth(); // 獲取寬度
view.getHeight(); // 獲取高度
}
});
}
2. View.OnLayoutChangeListener 監聽事件(API >= 11):
在layout發生改變前加入該事件,會被多次呼叫,因此在獲取到layout後 remove 該事件。
(用之前add,用完立即remove, 以免監聽到不必要的變動)
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
view.removeOnLayoutChangeListener(this);
view.getWidth(); // 獲取寬度
view.getHeight(); // 獲取高度
}
});
3.使用 View.post() 方法:
Runnable 對象中的方法會在 View 的 measure、layout 等事件完成後觸發。
UI 事件隊列會按順序處理事件,在 setContentView() 被調用後,事件隊列中會包含一個要求重新 layout 的 message,所以任何 post 到隊列中的 Runnable 對象都會在 Layout 發生變化後執行。
該方法只會執行一次,且邏輯簡單,建議使用。
view.post(new Runnable() {
@Override
public void run() {
view.getWidth(); // 獲取寬度
view.getHeight(); // 獲取高度
}
});
以上參考:
[Android] 獲取View的寬度和高度
@Override public void run() { // TODO Auto-generated method stub Layout layout = tvDoc.getLayout(); int a = layout.getLineForOffset(sbBe.abl[sbBe.curHit]); int y = layout.getLineTop(a); // e.g. I want to scroll to line // 40 y = Math.max(0, y - 50); sv.smoothScrollTo(0, y); } }, 100);//延遲100微秒