Android) ViewCompat.setOnApplyWindowInsetsListener 파헤치기

성승모·2024년 8월 1일
0
post-custom-banner

배경

Bottom Navigation Bar를 만드는 도중 Bar에 bottom padding이 추가되어 있었다.
검색을 통해 xml 단에서 여러 시도를 하였지만 결국 실패

  • padding=0
  • itemIconSize 조정

    이후 튜터님께 여쭤보고 해당 Activity의
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main))

부분을 삭제 또는 findByViewId(바텀 네비게이션의 뷰 id)로 하면 해결되었다. 따라서 ViewCompat.setOnApplyWindowInsetsListener에 대한 이해가 필요하다 생각되어 정리해보려 한다.

우선 ViewCompat이란?

  • 정의: View의 feature에 접근하는 것을 도와주는 도우미
  • 왜 필요한가? : API 버전별 차이점을 알아서 지원하도록 mapping
    -> SDK 버전을 일일이 체크하지 않아도 됨.
//미사용 시
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
	view.transition = TRASITION_NAME
}
//사용 시
ViewCompat.setTransitionName(view, TRASITION_NAME)

즉, View에 접근할 수 있으며 각 SDK 버젼에 따라 요청을 처리한다.

setOnApplyWindowInsetsListener

정의

: 마음대로 window insets를 바꾸기 위한 리스너이며 각 View마다 고유의 onApplyWindowInsets가 있다. 커스텀하기 위하여 setOnApplyWindowInsetsListener을 호출하여 insets을 조정한다.

insets?
: 시스템 UI나 기기의 하드웨어적 특성에 따라 App이 가려지는 것을 막기 위해 패딩을 얼만큼 더할지를 나타냄. 따라서 상하좌우의 네 방향의 값을 가지고 있음.

뜯어보기

처음 MainActivity를 만들면 있는 코드

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
    val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
    v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
    insets
}
  • findViewById로 커스텀할 View를 선택하여 넘긴다.
  • window insets을 커스텀할 View v와 v에 적용될 패딩값 insets를 파라미터로 받는다.
  • systemBar: 상태바, 타이틀바, 바텀바 등 모든 시스템 바를 뜻하며 여기서 Input Method Editor(키보드 등)은 제외된다.
    -> 따라서, systemBar의 기본 insets을 가져오는 것

<위 SystemBar Insets 값을 프린팅한것>

Bottom Padding이 132이다. 그렇기 때문에 Bottom Bar 아래부분에 패딩이 추가되었던 것이다.

그렇다면 만약 top과 bottom을 0으로 하면 어떻게 될까?


1. Top: 상태바까지 앱이 침범한다.
2. Bottom: 최하단에 뒤로가기,홈,정지 버튼에 가릴줄 알았는데, 가리진 않고 추가되었던 패딩값만 제거되었다.

조합으로 왜 그런지 알아보자.

고를 수 있는 조합
1. main insets의 bottom 값: 0 or default 값
2. Bottom Bar의 insets의 bottom 값: 0 or default 값

위 1번과 2번을 조합하면 총 네가지 경우를 얻을 수 있다.

조합1) main = 0, bottomBar = 0

조합2) main = default, bottomBar = 0

조합3) main = 0, bottomBar = default

조합4) main = default, bottomBar = default

추가 조합5) main = systemBar.bottom, bottomBar = default

추론

여러 조합을 통해 얻어낸 결과,
1. Main의 default bottom은 0인 것 같다.
2. BottomBar의 default bottom은 NavigationBar의 기본 크기만큼 인듯하다.
3. 자식 View Insets은 부모 View부터 시작하여 패딩값이 더해진다.

profile
안녕하세요!
post-custom-banner

0개의 댓글