티스토리 뷰
ViewTreeObserver 단어를 뜯어보면 View Tree + Observer 로 나눌 수 있습니다.
Android Developers 에서는 View Tree Observer를 다음과 같이 표현하고 있습니다.
View Tree Observer는 리스너 등록을 통하여 View Tree 안에서의 변화를 감지할 수 있습니다.
A view tree observer is used to register listeners that can be notified of global changes in the view tree. Such global events include, but are not limited to, layout of the whole tree, beginning of the drawing pass, touch mode change.... A ViewTreeObserver should never be instantiated by applications as it is provided by the views hierarchy. Refer to
View.getViewTreeObserver()
for more information.
사용방법
ViewTreeObserver에 대해서 어느정도 감은 잡았을거 같은데요. 그렇다면 어떻게 사용 하는것인지 알려드리겠습니다.
상황을 만들고 설명하는게 더 좋을거 같습니다.
사용자가 검색 화면에 진입했을 때 검색어 입력창(EditTextView)에 포커스를 두고 키보드를 보여주고 싶습니다.
ViewTreeObserver의 존재조차 몰랐을 경우 onCreated(또는 onCreatedView)에 키보드 보여주는 코드를 넣을 것입니다.
일부 기기는 보여지나 다른 기기에서는 동작 안하는 이슈를 발견하게됩니다.
좀 더 생각을 한다면 Handler.PostDelay() 로 뷰가 다 그려졌겠다 싶을 시간에 키보드를 보여주는 로직을 넣을 것입니다.
하지만 이 방법은 타이밍 이슈가 발생할 수 있습니다.
이런 불편함을 해결하는 방법으로 ViewTreeObserver을 통하여 View가 그려졌을 때를 notice 받아서 처리하도록 합니다.
전체 View가 그려졌음을 판단하는 함수는 viewTreeObserver.addOnGlobalLayoutListener 을 사용하면 됩니다.
여기서 주의할 점은 viewTreeObserver의 대상은 가장 상단 View로 지정해야합니다.
코틀린으로 작성된 소스를 보겠습니다.
// 전체 View가 들어있는지 Listener 등록
rootView.viewTreeObserver.addOnGlobalLayoutListener(
object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
etSearch.post{
etSearch.requestFocus()
etSearch.showKeyboard()
}
// 1회성을 위해 Listener 제거
rootView.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
옵저버 리스너를 등록한 후 변경에 있을 때 1회만 할 경우 반듯이 리스너를 제거해야 합니다. 만약 제거를 안했을 경우 무한 리스너 호출에 걸릴 수 있습니다.
다양한 ViewTreeObserve
dwfox 님의 블로그에 유용한 리스너를 깔끔히 정리하여 참고하여 작성하였습니다.
용도에 맞춰서 사용한다면 다양한 이벤트처리를 자유롭게 할 수 있을 것으로 예상됩니다.
형태 | Listener | 용도 |
interface | ViewTreeObserver.OnDrawListener | 뷰를 그릴 때 |
interface | ViewTreeObserver.OnGlobalFocusChangeListener | 전체 뷰의 포커스가 바뀔 때 |
interface | ViewTreeObserver.OnGlobalLayoutListener | 전체 뷰가 그려질 때 |
interface | ViewTreeObserver.OnPreDrawListener | 뷰가 그려지기 전 |
interface | ViewTreeObserver.OnScrollChangedListener | 스크로 상태의 변경시 |
interface | ViewTreeObserver.OnTouchModeChangeListener | 터치 모드 변경시 |
interface | ViewTreeObserver.OnWindowAttachListener | 뷰의 계층구조에 붙을 때와 떨어져 나갈때 |
interface | ViewTreeObserver.OnWindowFocusChangeListener | 윈도우 포커스 변경시 |
마무리
화면이 그려지기 전에 크기를 측정 시 NULL 또는 0 의 값을 나올 때가 있습니다.
ViewTreeObserver 를 몰랐던 저는 Handler.PostDelay 을 통하여 처리하였는데요.
ViewTreeObserver 을 알고부터는 타이밍 이슈가 발생할 위험성을 막을 수 있었습니다.
UI 구성하는데 보다 자유로워지길 희망하며 글을 마칩니다.
참고사항
https://developer.android.com/reference/android/view/ViewTreeObserver.html?hl=ko
'프로그래밍 > Android' 카테고리의 다른 글
ProcessLifecycleOwner 사용해보기 (0) | 2020.03.26 |
---|---|
크롬북(ChromeBook) 과 ADB IP 빌드 해보기 (0) | 2020.03.09 |
[Cordova] Android Studio 3.0 업데이트 후 에러 대응 방법 (2) | 2019.08.06 |
구글 로그인을 사용해보자 (0) | 2019.05.28 |
[Android] 네이버 로그인 사용해보자 (0) | 2019.05.27 |
- 코틀린
- 디자인패턴
- MCC
- Kotlin
- Android Studio
- swift
- 점수판
- 스코어헬퍼
- view
- 안드로이드
- IOS
- 선교
- 알고리즘
- Android
- 패턴
- java
- 탁구
- flutter
- 고시문헬퍼
- 고시문
- 임용고시
- missionchina
- issue
- missioon
- DI
- 미션차이나센터
- RXjava
- push
- IT
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |