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

물건은 많은데 보관할 공간이 없다면 어떻게 할까요? 수납장을 하나 장만해서 정리를 하면 될것입니다. 스마트폰의 화면은 작습니다. 대부분 한뼘크기도 안되는 화면을 가지고 있죠. 하지만 스마트폰의 어플리케이션에는 생각보다 다양한 기능이 들어가야만 합니다. 공간은 없는데 기능은 많이 들어가야하니 어플리케이션에도 수납장을 하나 장만해야겠군요. 안드로이드에 네비게이션 드로어라는 기능이 있습니다. 줄여서 네비바라고 부르는 기능입니다.

네비게이션드로어

위 사진은 네비게이션 드로어의 기본화면입니다. 작동법은 화면에서 왼쪽에서 오른쪽으로 쓸던지 액션바의 네비바 버튼을 누르면 튀어나옵니다. 어플리케이션 어느곳에서나 작동한다는 특징이 있기때문에 로그인이 필요한 어플리케이션일 경우 프로필정보를 주로 넣습니다. 


네비게이션 드로어(Navigation Drawer) 사용법

NavigationView를 사용하기 위해서는 DrawerLayout으로 Navigation을 감싸야 합니다. DrawerLayout은자신의 영역 안에서 자식 뷰(View)가 "Drawer(서랍)"와 같은 동작을 수행하도록 만들어주는 레이아웃입니다. 예제의 구조도는 아래와 같습니다.

구조

MainActivity

package com.example.user.mynavigation;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}

네비바의 디자인 및 기능을 수정할 수 있는 MainActivity입니다. 주요 메서드는  public boolean onNavigationItemSelected()입니다. R.id.아이콘을 설정하여 네비바의 아이콘 모양을 수정할수도 있으며 네비바 아이콘을 클릭할 시  public boolean onNavigationItemSelected()의 if문을 타게 됩니다. 이 if문안에 Intent를 걸어주어 다른 페이지로 이동시키게끔 할 수도 있습니다.


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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

메인화면 xml입니다. 


app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="match_parent"
    tools:context="com.example.user.mynavigation.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>


content_main.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="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.user.mynavigation.MainActivity"
    tools:showIn="@layout/app_bar_main">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>



nav_header_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="@dimen/nav_header_height"
    android:background="@drawable/side_nav_bar"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        app:srcCompat="@mipmap/ic_launcher_round" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:text="Android Studio"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android.studio@android.com" />

</LinearLayout>
네비바 헤더의 디자인이 이루어지는 xml입니다. 디자인을 수정하고싶으시면 이곳에서 수정하시면 됩니다.


댓글(8)

  • ㅜㅜ
    2018.10.22 21:12

    네비게이션 드로우 뷰를 사용해서 진행 중이였는데요
    프래그먼트로 화면전환 할때에 버튼들이 다른 화면에서 나오기하고 버튼의 기능을 하지 못해서
    include layou 부분을 주석처리 및 코드를 추가해줬더니
    버튼등을 잘 동작하는데 네비게이션 드로우가 안나타는데 해결 방안을 알수 있을까요?

    • 2018.10.22 21:14 신고

      글쎄요.... 이렇게 들어서는 뭐가 문제인지 정확하게는 파악하기가 힘드네요... 쉽게 네비게이션을 만드는 방법은 프로젝트 만들기 -> 네비게이션 프로젝트로 만들면 바로 구현하실 수 있으니 그렇게 한번 해보세요

  • ㅜㅜ
    2018.10.22 21:49

    프로젝트만들기를 통해서 네비게이션 프로젝트를 만들었는데요
    content_main.xml에 버튼 등을 작성을 해주었는데요
    에뮬이나 폰으로 확인 해보니까 버튼이 눌렀을때 로그캣 창에 ViewPostIme pointer 0, ViewPostIme pointer 1출력이 되는데 이때는 어떻게 해야되는지 문의 드립니다.

    • 2018.10.24 14:32 신고

      그거는 원래 뜨는거에요 아마 네비게이션이 열렸을때는 1이고 닫혀있을때는 0일걸요? 로그캣은 사용자한테는 안보이니까 놔둬도 되지않을까요?

  • 2019.08.07 18:56

    비밀댓글입니다

    • 2019.08.07 20:24

      비밀댓글입니다

  • 2019.08.08 10:23

    비밀댓글입니다

    • 2019.08.08 19:53 신고

      저도 안해봐서 방법은 모르겠는데...

      http://www.masterqna.com/android/70532/%EB%84%A4%EB%B9%84%EA%B2%8C%EC%9D%B4%EC%85%98-%EB%93%9C%EB%A1%9C%EC%9A%B0-%EC%98%A4%EB%A5%B8%EC%AA%BD-%EB%B6%80%EB%B6%84%EC%9D%B4-%EB%82%98%EC%98%A4%EA%B2%8C-%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80%EB%8D%B0-%EB%B0%A9%EB%B2%95%EC%9D%84-%EB%AA%A8%EB%A5%B4%EA%B2%A0%EC%96%B4%EC%9A%94

      해당글 한번 참조해보세요 [비밀댓글]

Designed by JB FACTORY