본문 바로가기

JAVA/Android

[JAVA][Android] 화면 변경을 감지하는 ViewTreeObserver

ViewTreeObserver 란 무엇인가?

 

https://developer.android.com/reference/kotlin/android/view/ViewTreeObserver?hl=en 

 

ViewTreeObserver  |  Android Developers

android.net.wifi.hotspot2.omadm

developer.android.com

요약하자면 화면에 특정 리소스가 로딩되거나 변경, 혹은 포커스 변경을 감지할 수 있는 Observer이다.

 

여러가지 리스너가 있지만 가장 유용한 두 가지를 소개하려고 한다.

 

import android.view.ViewTreeObserver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        
    ImageView imgView = findViewById(R.id.img_view);

    ViewTreeObserver imgViewTreeObserver = imgView.getViewTreeObserver();

    //#1
    imgViewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //동작
            Toast.makeText(mContext,imgView.getHeight(),Toast.LENGTH_SHORT).show();

            //listener 해제
            imgViewTreeObserver.removeOnGlobalLayoutListener(this);
        }
    });
    
    //#2
    imgViewTreeObserver.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
    @Override
    public void onGlobalFocusChanged(View oldFocus, View newFocus) {
            //동작
            Toast.makeText(mContext,"focus is changed",Toast.LENGTH_SHORT).show();

            //listener 해제
            imgViewTreeObserver.removeOnGlobalFocusChangeListener(this);
    	}
    });
}

 

화면에 리소스가 로딩되기 전에 리소스에 대한 값을 추출하려고 하면 무의미 한 값이 나올 수 있는데,
OnGlobalFocusChangeListener는 그런 케이스에 유용하게 사용할 수 있다.

 

사용법은 간단하다.

ViewTreeObserver 클래스를 import한 후, 원하는 이미지뷰나 다른 객체에서 getViewTreeObserver()를 이용해 

observer 객체를 생성한 뒤, 원하는 리스너를 등록하면 된다.

화면 변경이 감지되면 해당 리소스가 호출되고 정의한 동작을 수행한다.

 

#1 : OnGlobalLayoutListener -> 레이아웃 변경에 대한 감지

#2 : OnGlobalFocusChangeListener -> 포커스 변경에 대한 감지

 

주의할 점은 로딩되는 시점에 작업을 수행하기 위해 해당 리스너를(#1) 사용하는 경우에는

작업을 한 뒤 리스너를 반드시 해제해 주어야 한다.

 

removeGlobalOnLayoutListener(this);
removeOnGlobalFocusChangeListener(this);

 

이 작업이 누락되면 리스너가 무한으로 호출될 수 있다.