반응형

대부분의 앱에는 액티비티 하단에 BottomNavigationView 를 사용합니다.

 

여러 앱에서 자주 애용되는 화면 하단의 탭 버튼같은 네비게이션 뷰입니다. 구현 방법도 많이 어렵지 않기에 많은 학생들이 포트폴리오용 앱을 만들때 대부분 포함하는 뷰입니다.

 

근데 android 15(api 35) 버전부터 강제로 적용되는 EdgeToEdge UI 에서 BottomNavigationView 를 기존 구현방식대로 했다가 높이가 이상해지는 문제가 발생했습니다.

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    app:menu="@menu/bnv"
    app:labelVisibilityMode="labeled"/>

 

위처럼 보통 BottomNaviationView 의 높이(height) 을 아이콘과 라벨글씨를 감쌀 크기인 wrap_content 를 지정하여 구현합니다.

android studio 의 XML 레이아웃 파일 작성할때 보이는 프리뷰의 모습을 보면 크게 문제가 없어 보입니다.

 

 

근데 실제 디바이스에 실행해 보면 아이콘과 글씨영역 외에 아래쪽에 빈 영역이 보입니다.

 

이렇게 아래쪽에 빈 영역이 생기는 이유는 바로 시스템바(상태바+네비게이션바) Insets 에 대응한 패딩이 BottomNavigationView 에 기본 적용되어 버린 결과입니다.

Edge To Edge UI 는 액티비티가 화면 전체를 사용하게 되고 이로인해 뷰들이 시스템바(상태바+네비게이션바)의 영역에 가려지는 문제를 해결하기 위해 Kotlin 파일에서 적용한 시스템바 만큼의 동적인 패딩적용코드를 사용합니다.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        //시스템바 사이즈를 얻어와서 그 만큼 최상위 뷰에 패딩을 적용하는 코드
        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
        }
    }
}

 

BottomNaviationView 는 기본적으로 하단에 배치되도록 설계된 만큼 기본적으로 아래쪽의 시스템바(네비게이션바) 영역에 대한 고려를 해서 그만큼 bottom 패딩이 포함되어 제공된 것 같습니다. 이전 버전에서는 없었던 새로운 변경사항입니다.

 

그래서 이미 액티비티 코틀린 코드에 작성된 bottom 패딩에 더해 BottomNavigationView 의 bottom 패딩이 추가로 보여진 상황이 발생된 것 입니다. 

 

해결 Solusion

방법1. 액티비티 최상위 뷰에 적용된 bottom 패딩을 주지 않기.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())

            //BottomNavigationView 자체가 네비게이션바에 대한 Insets 을 고려하여 아래쪽 패딩이 포함되어 있음.
            //그래서 BNV 를 사용할 때는 아래쪽 패딩을 사용하지 않도록...
            //v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, 0)
            insets
        }
    }
}

 

 

방법2. BottomNavigationView에 포함된 bottom 패딩을 주지않기.

//BottomNavigationView 의 패딩을 리스너를 통해 모두 0 으로 변경 
val bnv:BottomNavigationView = findViewById(R.id.bnv)
ViewCompat.setOnApplyWindowInsetsListener(bnv){ v, insets ->
    v.setPadding(0,0,0,0)
    insets
}

 

 

♣실행결과 

 

반응형

+ Recent posts