[안드로이드] 네비게이션 드로어 (Navigation drawer) 사용법



navigation drawer 구글 머티리얼 디자인 가이드 중 네비게이션 드로어

네비게이션 드로어는 화면 왼쪽 가장자리에 위치해 있고 앱을 탐색할 수 있는 하나의 패널입니다.

이걸 잘 활용한다면 특정 메뉴를 찾기 위해 클릭이 많이 일어나는 (Deep depth) 문제를 해결할 수 있습니다.

평상시에는 화면 밖에 가려져 있지만 왼쪽 스와이프나 왼쪽 상단 메뉴 버튼을 클릭하면 위 사진처럼 나옵니다.

그럼 네비게이션 드로어를 어떻게 구현하는지 알아보겠습니다.



1. Result

navigation drawer result 이번 포스팅에서 진행한 네비게이션 드로어 결과 화면



2. Step by Step

2-1. 안드로이드 서포트 라이브러리 추가

  • 진행에 앞서 네비게이션 드로어는 서포트 라이브러리에 포함되어 있기 때문에 App Gradle 에 의존성 라이브러리를 넣어줘야합니다.

  • 최근 안드로이드 스튜디오에서 새 프로젝트를 만들면 기본으로 서포트 라이브러리들이 들어가 있지만, 혹시 확인해보고 없으시다면 아래 라이브러리를 Gradle 에 추가해주세요.

build.gradle (app)

implementation 'com.android.support:design:27.1.1'


2-2. 네비게이션 메뉴 추가

navigation menu

  • 네비게이션 드로어에서 보여줄 메뉴들을 추가합니다.

  • 메뉴들에 포함되는 아이콘은 미리 /res/drawable/ 에 준비해주세요. ( New > Vector Asset 으로 추가하면 편합니다.)

_/res/menu/main_navigationmenu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
                android:id="@+id/account"
                android:icon="@drawable/ic_account_circle_black_24dp"
                android:title="계정"
        />
        <item
                android:id="@+id/star"
                android:icon="@drawable/ic_star_black_24dp"
                android:title="즐겨찾기"
        />
        <item
                android:id="@+id/cart"
                android:icon="@drawable/ic_shopping_cart_black_24dp"
                android:title="장바구니"
        />
    </group>
    <group android:checkableBehavior="single">
        <item
                android:id="@+id/bug_report"
                android:icon="@drawable/ic_bug_report_black_24dp"
                android:title="버그 리포트"
        />
        <item
                android:id="@+id/setting"
                android:icon="@drawable/ic_settings_black_24dp"
                android:title="설정"
        />
        <item
                android:id="@+id/logout"
                android:icon="@drawable/ic_exit_to_app_white_24dp"
                android:title="로그아웃"
        />
    </group>
</menu>


2-3. 네비게이션 헤더 추가 (Optional)

navigation header

  • 네비게이션 헤더 부분은 하셔도 되고, 내가 만들 앱에 필요 없으시면 굳이 안넣으셔도 됩니다.

  • 헤더는 레이아웃이기 때문에 /res/layout 에 파일을 만들어주시면됩니다.

  • 나중에 DrawerLayout 에서 헤더를 설정할 때 사용됩니다.

_/res/layout/main_navheader.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="230dp"
        android:background="@color/colorPrimary">

    <ImageView
            android:layout_width="wrap_content"
            android:layout_height="150dp" tools:srcCompat="@tools:sample/avatars"
            android:id="@+id/imageView"
            app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="24dp"
            android:layout_marginTop="4dp" app:layout_constraintTop_toTopOf="parent"/>
    <TextView
            android:text="Charlie Park"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:id="@+id/textView" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="24dp"
            android:layout_marginTop="12dp" app:layout_constraintTop_toBottomOf="@+id/imageView"
            android:textColor="#fff"/>
    <TextView
            android:text="kiwinam@test.com"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView2" android:textSize="10sp"
            android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/textView"
            android:layout_marginStart="24dp" app:layout_constraintStart_toStartOf="parent" android:textColor="#fff"/>
</android.support.constraint.ConstraintLayout>


2-4. 메인 레이아웃 수정

main layout

  • 네비게이션 드로어를 사용할 메인 레이아웃을 수정합니다.

  • 여기서 포인트는 메인 레이아웃의 최상단 레이아웃이 DrawerLayout 이여야 네비게이션 드로어 가 정상적으로 동작합니다.

  • DrawerLayout 의 자식 레이아웃으로 NavigationView 를 설정해주시면 됩니다.

  • NavigationView 에서 방금 만든 메뉴와 헤더를 설정합니다.

_/res/layout/activitymain.xml

<?xml version="1.0" encoding="utf-8"?>
<!--parent layout-->
<android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        >
    <!-- main layout-->
    <RelativeLayout
            android:layout_width="match_parent" android:layout_height="match_parent"
            android:background="#fff">
        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/colorPrimary"
                app:contentInsetStart="0dp"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        />
        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="test"
                android:layout_centerInParent="true"/>
    </RelativeLayout>

    <!--navigation drawer-->
    <android.support.design.widget.NavigationView
            android:id="@+id/navigationView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/main_nav_header"
            app:menu="@menu/main_navigation_menu"
    />

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


2-4. Activity 수정

  • 네비게이션 드로어는 레이아웃 설정이 대부분이고 실제 코틀린이나 자바 코드는 많이 사용하지 않아도 구현 가능합니다.

  • 이번 예제에서도 (1)메뉴 버튼을 눌렀을 때 네비게이션이 나오도록 처리하거나 (2)버튼 클릭 리스너를 설정해주는 코드만 넣어보겠습니다.

(1) 메뉴 버튼 클릭 시 네비게이션 드로어 열기

MainActivity.kt

// 툴바 메뉴 버튼이 클릭 됐을 때 콜백
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    // 클릭된 메뉴 아이템의 아이디 마다 when 구절로 클릭시 동작을 설정한다.
    when(item!!.itemId){
        android.R.id.home->{ // 메뉴 버튼
            drawerLayout.openDrawer(GravityCompat.START)    // 네비게이션 드로어 열기
        }
        R.id.menu_search-> Snackbar.make(toolbar,"Search menu pressed",Snackbar.LENGTH_SHORT).show()
        R.id.menu_account-> Snackbar.make(toolbar,"Account menu pressed",Snackbar.LENGTH_SHORT).show()
        R.id.menu_logout-> Snackbar.make(toolbar,"Logout menu pressed",Snackbar.LENGTH_SHORT).show()
    }
    return super.onOptionsItemSelected(item)
}
  • 메뉴 버튼이 클릭되면 drawerLayout.openDrawer(GravityCompat.START) 를 호출하여 네비게이션 드로어를 열어줍니다.


(2) 네비게이션 메뉴 버튼 클릭 리스너 설정

  • 먼저 네비게이션 메뉴 클릭 리스너를 클래스에 implement 하겠습니다.

MainActivity.kt

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

  • 그런 다음 onNavigationItemSelected 메서드를 오버라이드하여 클릭 시 어떤 처리를 해줄지 설정합니다.

MainActivity.kt

// 네비게이션 드로어 메뉴 클릭 리스너
override fun onNavigationItemSelected(item: MenuItem): Boolean {
    when(item.itemId){  // 네비게이션 메뉴가 클릭되면 스낵바가 나타난다.
        R.id.account->Snackbar.make(toolbar,"Navigation Account pressed",Snackbar.LENGTH_SHORT).show()
        R.id.setting->Snackbar.make(toolbar,"Navigation Setting pressed",Snackbar.LENGTH_SHORT).show()
    }
    drawerLayout.closeDrawers() // 기능을 수행하고 네비게이션을 닫아준다.
    return false
}
  • 이번 예제에서는 스낵바만 표시하도록 하였습니다.

  • 스낵바를 표시한 다음 네비게이션 드로어를 닫아줌으로써 사용자 경험을 매끄럽게 해줍니다.

여기까지 구현 하였으면 기본적인 네비게이션 드로어 사용법은 다 알수 있습니다.


2-5. 뒤로가기 클릭 시 네비게이션 닫기 (Optional)

back click

보통 사용자들이 네비게이션 드로어가 열려있을 때 뒤로가기 버튼을 누르면 네비게이션이 닫힐 것을 기대하는데, 이대로 코드를 진행하면 그렇게 동작하지 않습니다.

추가적으로 뒤로가기 버튼을 눌렀을 때 네비게이션 드로어를 닫아보겠습니다.

MainActivity.kt

/*
 * 뒤로가기 버튼으로 네비게이션 닫기
 *
 * 네비게이션 드로어가 열려 있을 때 뒤로가기 버튼을 누르면 네비게이션을 닫고,
 * 닫혀 있다면 기존 뒤로가기 버튼으로 작동한다.
 */
override fun onBackPressed() {
    if(drawerLayout.isDrawerOpen(GravityCompat.START)){
        drawerLayout.closeDrawers()
    }else{
        super.onBackPressed()
    }
}

뒤로가기 버튼을 눌렀을 때 닫히는 네비게이션 드로어



3. Source Code

전체 소스코드는 GitHub 에 연동해놓았습니다.

읽어주셔서 감사합니다.

제 글이 도움 되길 바랄게요.