Android ViewTreeObserver


안드로이드에서 뷰는 메인쓰레드에서 그려지게 되는데, 간혹 뷰의 높이나 넓이를 알고 싶은데 그려지고 있는 시점에 확인하게 되면 값이 들어 오지 않는 경우가 있다. 그래서 뷰가 메인쓰레드에서 정상적으로 생성이 완료되는 시점을 알아야 하는 경우가 있다.

모든 뷰에는 ViewTreeObserver가 있으며 getViewTreeObserver()를 통해서 얻어 올 수 있다. 여기에 뷰와 관련된 interface를 제공하여 뷰의 상태를 전달 받을 수 있다. 주요 Listener는 다음과 같다. 

  • OnGlobalFocusChangeListener – 뷰의 포커스 변경시 호출
  • OnGlobalLayoutListener – 뷰의 변경이 생기면 호출
  • OnPreDrawListener – 뷰가 그려지기전 호출
이중에 OnGlobalLayoutListener를 이용하면 뷰가 그려진 후의 시점을 알 수 있다. 코드는 다음과 같다. 
private View mView;

private OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            mView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
        
        //TODO mView의 높이를 구하는 등의 작업.

    }
};

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener)
}

addOnGlobalLayoutListener는 한번 사용한 후 반드시 삭제를 해야한다. 뷰의 변경이 생기면 또 호출 되게 기때문에 한번 Callback된 후의 시점을 알고 난 후에는 Listener를 삭제하면 된다. 

삭제 하는 메서드는 젤리빈이후로 이름이 변경되여 다음과 같이 버전별로 처리 해야한다.