태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

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

2014.11.17 15:40

네비게이션 드로어는 꽤 오래 전부터 널리 사용되던 패턴 중 하나입니다. 그러다 보니, 공식 버전의 네비게이션 드로어가 없을 때부터 시작하여 현재 널리 사용되는 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: 상태바 배경 색을 지정합니다. 알파 값을 주어 반투명으로 표시되도록 설정했습니다.

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


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



저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

커니 유저 인터페이스/Material Design , , , , , , , , , , , , ,

  1. Blog Icon
    안녕하세요

    예제 다운 받아서 실행시켜보려고 하는데 자꾸 console 창에서 이러한 에러가 나네요

    NavigationDrawerOveray\res\values-v21\styles.xml:4: error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCompat.NoActionBar'.

    스타일 부분 보니까 NoActionBar라는게 없는거 같은데 어떻게 해야 하나요??

    참고로 appCompat-v7 추가했습니다.

  2. appcompat-v7 라이브러리 버전을 21.0.0 이상으로 지정하셨나요?

  3. Blog Icon
    안녕하세요

    네 적용하였습니다. 근데 잘 안되네요..ㅜㅜ

    근데 혹시 안드로이드 스튜디오로 개발하신 건가요?

    저는 이클립스를 사용중인데 에제를 받아서 해보니 여러가지 에러가

    발생하더라구요 클래스를 찾지못한다던가.. 테마가 없다던가

    혹시 이클립스로 해서 그런건가요??

    만약 그렇다면 이클립스로 material Design 네이비게이션 드로어

    적용하는 방법 없을까요??

    아 그리고 현재 넥서스5에서 개발하고 있습니다. 그래서 서포트 라이브러리 v7를 사용하지 않고 있습니다.

  4. 네, 예제는 안드로이드 스튜디오 기준입니다.
    이클립스도 appcompat-v7 을 라이브러리 프로젝트로 추가하면 사용 가능합니다.
    그리고, 안드로이드 5.0 이상만 지원할 것이 아니라면 서포트 라이브러리를 사용하셔야 합니다.

  5. Blog Icon
    안녕하세요

    감사합니다 해결했습니다~

  6. Blog Icon
    방문객

    안녕하세요~ 매번 감사히 포스팅 잘 보고 있습니다!
    이번 글을 보니까 문득 궁금증이 생기는게, LMT launcher 혹은 pie control 처럼 스크린 양 사이드에서 한손으로 동작할 수 있는 소프트 버튼의 구현도 저 네비게이션 드로어를 이용한건가요?
    제가 요새 개발하려는 어플에도 위에서 말한 소프트 버튼을 구현하고 싶은데 관련 자료를 찾기가 힘드네요.
    조언부탁드립니다~

  7. 네이게이션 드로어를 쓴 것 같진 않고, 제스처만 감지해서 메뉴를 화면에 띄워주는 것으로 보입니다.

    ViewDragHelper (https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/widget/ViewDragHelper.java) 를 참고해보세요~

  8. Blog Icon
    호야

    포스팅 정말 잘보고있습니다 ㅠ
    그런데 이게 안드로이드상의 버그인지 ㅠㅠ imageView 나 textView나 드로워 안에있으면
    코드상으로 setBackground 나 setBackgroundResources나 setImageResources나 xml로만들어놓은 쉐이프로 드로잉하려면
    아무것도 안나와요... 이게 버그인지 뭔지... 저 메소드만 작동을 안해요 ㅠㅠ drawable.xml
    이걸 해결할 방법이없을까요 ㅠ?

  9. 화면이 아예 안 보이는 건 아닌가요?
    드로어 안에 있다고 해서 특별히 다를 건 없는데요, 아무것도 안 보인다면 뷰의 순서 배치가 잘못 되었을 가능성도 있습니다.