본문 바로가기

유저 인터페이스/Material Design

액티비티 전체를 덮는 네비게이션 드로어 만들기

네비게이션 드로어는 꽤 오래 전부터 널리 사용되던 패턴 중 하나입니다. 그러다 보니, 공식 버전의 네비게이션 드로어가 없을 때부터 시작하여 현재 널리 사용되는 AppCompat 버전의 네비게이션 드로어까지 생각보다 다양한 종류의 구현이 있습니다.


하지만, 지금까지 네비게이션 드로어에 대한 정확한 가이드라인은 없었습니다. 때문에, 같은 패턴임에도 불구하고 다른 동작과 외형을 보여주게 되어 사용자들에게 혼란을 주기도 했습니다.


이 문제를 구글에서도 인식했는지, 안드로이드 5.0과 함께 발표된 '머티리얼 디자인'의 가이드라인에서는 네비게이션 드로어가 어떻게 표시되어야 하는지 명확하게 제시하고 있습니다. 다음 그림을 통해 휴대폰과 태블릿에서 네비게이션 드로어가 어떻게 표현되어야 하는지 확인할 수 있습니다. 

(그림 출처: http://www.google.com/design/spec/layout/structure.html#structure-ui-regions-guidance)


휴대폰에서 표시하는 경우



태블릿에서 표시하는 경우


그림에서 확인할 수 있듯이, 가장 많이 사용하는 왼쪽 네비게이션 드로어는 네비게이션 바(소프트키 부분)을 제외하고 상태바 및 앱 바(App bar)를 모두 덮도록 가이드하고 있습니다. 


이번 포스트에서는 위의 가이드라인에 맞게 네비게이션 드로어를 만드는 방법을 알아보겠습니다.


프로젝트 준비


이번 프로젝트는 이전에 작성한 포스트 (2014/11/16 - 네이게이션 드로어에 머티리얼 디자인 적용하기) 에서 작성한 예제를 조금 변경하여 진행합니다. 이전 포스트를 아직 보지 않으셨다면 확인 후, 이어서 이 글을 계속 읽어 주세요.


이전에 다음과 같이 머티리얼 디자인이 적용된 네비게이션 드로어를 제작했습니다. 하지만, 새로운 가이드라인과 달리 기존의 AppCompat처럼 드로어가 화면의 일부만 덮고 있습니다.




레이아웃 변경


가이드라인과 같이 네비게이션 드로어가 하단 소프트키 영역을 제외한 모든 부분을 덮도록 하려면 레이아웃을 변경해야 합니다.

다음과 같이 액티비티의 레이아웃을 변경합니다.


[activity_main.xml]

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize" />


        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#303F9F" />

    </LinearLayout>

    <View
        android:id="@+id/drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#3F51B5"
        android:fitsSystemWindows="true" />


</android.support.v4.widget.DrawerLayout>

기존 레이아웃 대비 변경된 점은 다음과 같습니다.


  • DrawerLayout을 루트 레이아웃으로 설정

  • DrawerLayout 및 드로어 영역(@+id/drawer) 뷰에 android:fitsSystemWindows="true" 속성 추가


액션바를 툴바로 대체했기 때문에, DrawerLayout 내에 툴바를 넣어 자연스럽게 드로어 영역이 툴바를 가릴 수 있게 되었습니다.
android:fitsSystemWindows 속성은 뷰가 차지할 수 있는 영역을 상태바 및 소프트키 영역을 제외한 영역까지 확장해주는 역할을 합니다.

values-v21/styles.xml 추가

위 가이드라인에선 드로어 영역이 상태바 하단으로 표시되도록 되어 있는데, 이는 fitsSystemWindows 속성과 상충됩니다. 이 문제를 해결하려면 상태바 영역 아래에도 다른 컨텐츠가 그려질 수 있도록 조정해 주어야 하는데요, 이를 위해 values-v21 폴더를 만들어 styles.xml 파일을 추가한 후, 다음 내용을 추가합니다.

[values-v21/styles.xml]
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">#33000000</item>
    </style>

</resources>


values-v21을 사용하는 것에서 눈치 채셨겠지만, 위의 방법은 안드로이드 5.0 이상에서만 사용 가능합니다. 이전 버전에서도 비슷한 방식의 UI를 구성하는 것은 가능하지만, 그 절차가 매우 까다로워 별로 권장하고 싶지 않네요. 구글 앱들도 안드로이드 5.0 에서만 상태바 하단에 네비게이션 드로어가 표시되고, 하위 버전에선 툴바만 덮는 것으로 보아 위 방법대로 적용하면 무난할 것으로 보입니다.


위에서 추가한 두 가지 속성에 대해 정리하면 다음과 같습니다.


  • android:windowDrawsSystemBarBackgrounds: 상태바 아래에 다른 뷰가 표시될 수 있도록 합니다. 단, 네비게이션 바 부분은 제외합니다. (일반적인 경우와 마찬가지로 네비게이션 바 위에 뷰가 표시됩니다)
  • android:statusBarColor: 상태바 배경 색을 지정합니다. 알파 값을 주어 반투명으로 표시되도록 설정했습니다.

이것으로 모든 작업이 끝났습니다. 이전에 작성한 예제에서 코드 부분은 수정하지 않아도 됩니다.
완성된 예제를 실행하면 다음과 같이 네비게이션 드로어가 상태바 하단에 표시되면서, 모든 화면을 덮는 모습을 확인할 수 있습니다.


이 포스트에서 사용한 예제는 다음 링크에서 확인할 수 있습니다.