Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android 액션바(ActionBar)에 NavigationView 통합하는 방법

NavigationView란 무엇인가?

NavigationView 예제를 살펴보기 전에 먼저 NavigationView가 어떤 요소인지 이해할 필요가 있습니다. NavigationView는 HTML의 슬라이딩 메뉴와 유사한 UI 컴포넌트로, 네비게이션 드로어(Navigation Drawer)를 확장하여 만들어진 것입니다. 주로 다른 액티비티로 화면을 전환하거나 프로필 정보를 표시하는 용도로 활용됩니다.

이 글에서는 Android 액션바(ActionBar)에 NavigationView를 통합하는 과정을 단계별로 자세히 알아보겠습니다.

1단계: 새 프로젝트 생성

Android Studio에서 File → New Project로 이동한 후, 새 프로젝트 생성에 필요한 모든 정보를 입력합니다.

2단계: Navigation Drawer Activity 선택

프로젝트를 생성할 때 아래 그림과 같이 Navigation Drawer Activity를 선택해야 합니다.

Android 액션바(ActionBar)에 NavigationView 통합하는 방법

Navigation Drawer Activity를 선택한 뒤 'Next' 버튼을 클릭하여 프로젝트 생성을 마무리합니다.

3단계: 자동 생성된 레이아웃 파일 살펴보기

프로젝트 구조에서 layout 폴더를 열어보면 Android Studio가 여러 개의 레이아웃 파일을 자동으로 생성한 것을 확인할 수 있습니다.

activity_main.xml — 메인 액티비티 레이아웃

이 파일은 MainActivity의 레이아웃입니다. 부모 레이아웃으로 DrawerLayout을 사용하고, 그 안에 자식 요소로 NavigationView를 배치합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:app = "https://schemas.android.com/apk/res-auto"
    xmlns:tools = "https://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>

NavigationView는 크게 두 가지 레이아웃으로 구성됩니다. 바로 헤더 레이아웃(Header Layout)메뉴 레이아웃(Menu Layout)입니다. 헤더 레이아웃은 NavigationView 상단에 표시되는 헤더 정보를 담당하고, 메뉴 레이아웃은 메뉴 목록 정보를 담고 있습니다.

app_bar_main.xml — 앱바 레이아웃

일반적인 레이아웃 파일과 비슷하지만, 앱바 레이아웃(액션바)과 중앙 콘텐츠 영역에 대한 정보를 함께 포함하고 있다는 점이 특징입니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:app = "https://schemas.android.com/apk/res-auto"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    tools:context = ".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.CoordinatorLayout>

위 레이아웃에는 content_main 레이아웃이 포함되어 있습니다. 이곳이 바로 사용자가 자신만의 뷰를 자유롭게 구성할 수 있는 메인 콘텐츠 영역입니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:app = "https://schemas.android.com/apk/res-auto"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    app:layout_behavior = "@string/appbar_scrolling_view_behavior"
    tools:context = ".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 — 네비게이션 헤더

네비게이션 헤더 뷰로, NavigationView 상단에 표시되는 헤더 정보를 담습니다. 아래와 같이 헤더를 커스터마이징했습니다.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:app = "https://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:paddingLeft = "@dimen/activity_horizontal_margin"
    android:paddingTop = "@dimen/activity_vertical_margin"
    android:paddingRight = "@dimen/activity_horizontal_margin"
    android:paddingBottom = "@dimen/activity_vertical_margin"
    android:theme = "@style/ThemeOverlay.AppCompat.Dark">
    <ImageView
        android:id = "@+id/imageView"
        android:layout_width = "wrap_content"
        android:layout_height = "100dp"
        android:contentDescription = "@string/nav_header_desc"
        android:paddingTop = "@dimen/nav_header_vertical_spacing"
        app:srcCompat = "@drawable/logo" />
    <TextView
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:paddingTop = "@dimen/nav_header_vertical_spacing"
        android:textColor = "#FFF"
        android:textStyle = "bold"
        android:text = "Tutorials Point"
        android:textAppearance = "@style/TextAppearance.AppCompat.Body1" />
    <TextView
        android:id = "@+id/textView"
        android:textColor = "#FFF"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "Father of all educational website" />
</LinearLayout>

참고: 위 코드에는 drawable/logo가 사용되었으므로, 실제 앱을 개발할 때는 반드시 본인의 로고 이미지로 교체하세요.

activity_main_drawer.xml — 메뉴 레이아웃

menu/activity_main_drawer.xml 경로에 위치한 메뉴 레이아웃 파일입니다.

<?xml version = "1.0" encoding = "utf-8"?>
<menu xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:tools = "https://schemas.android.com/tools"
    tools:showIn = "navigation_view">
    <group android:checkableBehavior = "single">
        <item
            android:id = "@+id/nav_camera"
            android:icon = "@drawable/ic_menu_camera"
            android:title = "Import" />
        <item
            android:id = "@+id/nav_gallery"
            android:icon = "@drawable/ic_menu_gallery"
            android:title = "Gallery" />
        <item
            android:id = "@+id/nav_slideshow"
            android:icon = "@drawable/ic_menu_slideshow"
            android:title = "Slideshow" />
        <item
            android:id = "@+id/nav_manage"
            android:icon = "@drawable/ic_menu_manage"
            android:title = "Tools" />
    </group>
    <item android:title = "Communicate">
        <menu>
            <item
                android:id = "@+id/nav_share"
                android:icon = "@drawable/ic_menu_share"
                android:title = "Share" />
            <item
                android:id = "@+id/nav_send"
                android:icon = "@drawable/ic_menu_send"
                android:title = "Send" />
        </menu>
    </item>
</menu>

4단계: MainActivity.java 코드 작성

src/MainActivity.java에 다음 코드를 추가합니다.

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);
        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) {
        // 메뉴를 인플레이트하여 액션바에 항목을 추가합니다.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 액션바 항목 클릭을 처리합니다.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // 네비게이션 뷰 항목 클릭을 처리합니다.
        int id = item.getItemId();
        if (id == R.id.nav_camera) {
            // 카메라 동작 처리
        } 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;
    }
}

드로어 닫기 및 위치 변경

NavigationView를 닫으려면 아래와 같이 드로어를 닫으면 됩니다.

if (drawer.isDrawerOpen(GravityCompat.START)) {
    drawer.closeDrawer(GravityCompat.START);
}

NavigationView의 표시 위치를 변경하려면 다음 코드를 사용합니다.

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.END);

애플리케이션 실행하기

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하세요. 실행 옵션에서 본인의 모바일 기기를 선택하면, 기기 화면에 기본 화면이 표시되는 것을 확인할 수 있습니다.

Android 액션바(ActionBar)에 NavigationView 통합하는 방법