EdgeToEdge 적용 시 UI 곂치는 이슈 해결

이성민·2025년 3월 28일
1

안드로이드

목록 보기
18/19

구글이 앞으로 Android 15 이상 단말에서 targetSdkVersion 이 35 이상인 앱을 실행하면 강제로 edge-to-edge 를 적용한다고 발표했다.

EdgeToEdge 란?

앱 컨텐츠를 System Bar (status bar + navigation bar) 영역까지 확장하여 표시하게 만드는 것을 말한다. 쉽게 말해 status bar 와 navigation bar 를 투명하게 만들어서 앱 컨텐츠가 보이게 만드는 것을 말한다.

화면의 공간을 최대한 활용하므로 유저들에게 더 몰입감 있는 경험을 제공할 수 있으며, 앱의 콘텐츠와 시스템 UI 가 더 통합된 느낌을 준다. 하지만 사진에서 볼 수 있드시

이렇게 UI 가 곂치는 현상이 발생하므로 만약 액션이 들어가 있는 버튼이 해당 Bar 와 곂쳐있다면 불편함을 야기할 수 있다고 판단했다. 따라서 해당 이슈를 대응하는 방법을 찾아보았다.

BaseActivity 에서 동적으로 Padding 값 주기!

단말마다 System Bar 의 크기가 다를 수 있기에 고정 Padding 값을 주는 것은 위험할 수 있다.

private fun applyTopBottomPaddingForEdgeToEdge(rootView: View) {
    ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, insets ->
        // 상태바와 내비게이션 바 높이 얻기
        val statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top
        val naviBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
        
        // 키보드가 올라왔을 때 아래쪽 패딩 계산
        val bottomPadding = getBottomPaddingChangedByKeyboard(view, naviBarHeight)
        
        // 상단/하단 패딩 적용
        view.setPadding(0, statusBarHeight, 0, bottomPadding)
        insets
    }
}

private fun getBottomPaddingChangedByKeyboard(view: View, naviBarHeight: Int): Int {
    // 화면에 키보드가 올라왔는지 확인하고, 올려졌으면 키보드 높이만큼 패딩 적용
    val rect = Rect().apply { view.rootView.getWindowVisibleDisplayFrame(this) }
    return if (isKeyBoardVisible(view.height, rect)) {
        view.height - rect.bottom
    } else {
        naviBarHeight
    }
}

private fun isKeyBoardVisible(screenHeight: Int, rect: Rect): Boolean {
    // 키보드가 화면에 올라왔는지 체크 (높이가 화면 높이의 13% 이상일 경우 키보드가 올라왔다고 판단)
    val keyboardHeight = screenHeight - rect.bottom
    return keyboardHeight > screenHeight * 0.13
}

이렇게 동적으로 상단 Status Bar 하단 Navigation Bar 의 크기를 구해서 Padding 을 적용하도록 작업하였다.

private fun applyStatusBarColorForEdgeToEdge() {
    // 상태바 색상 변경
    window.statusBarColor = getColor(android.R.color.black)
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        // 안드로이드 R 이상에서는 시스템 바 스타일을 변경
        window.insetsController?.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS)
    } else {
        // 안드로이드 R 미만에서는 SYSTEM_UI_FLAG_LIGHT_STATUS_BAR을 제거
        window.decorView.systemUiVisibility = window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
    }
}

또한 Padding 값을 주었을 때 Status Bar 의 배경과 아이콘 색상을 지정해주어야 기존의 UI 를 유지할 수 있다.

abstract fun getViewBinding(): T

override fun onCreate(savedInstanceState: Bundle?) {
	enableEdgeToEdge()
    super.onCreate(savedInstanceState)
    ...
    binding = getViewBinding()
    applyStatusBarColorForEdgeToEdge()
    applyTopBottomPaddingForEdgeToEdge(binding.root)
}

BaseActivity 의 onCreate() 에 오버라이딩하면 모든 액티비티에서 값이 적용되어 나타나게 된다.

profile
Android Developer 이성민입니다

0개의 댓글