본문 바로가기
개발/안드로이드 개발

[안드로이드] Navigation Drawer Activity 알아보기

by 똘똘이박사 2016. 7. 6.

· 최초작성 : 2016. 07. 06.

최종수정 : 2016. 07. 06.

· 작성/수정내용 :

  - Android Studio 기본 템플릿 - 'Navigation Drawer Activity' 알아보기




시작하기에 앞서


상당히 오래 간만에 다시 강좌를 이어 가네요

사실 현재 맡은 업무가 개발이 아니기에 먹고 살기 위해서 잠시 개발 관련된 부분은 접어 두고 있었습니다.

이제 조금 여유가 생겼고 또 만들고 싶은 앱이 생겼으니 간단한 프로그램들을 만들면서 강좌를 이어가 볼까 합니다. 

 테스트 설정

 - Android Studio 2.1.2

   (2016.07.06 최신 업데이트)

 - min SDK :  API 19

 - 기본 포멧



지난 마지막 마테리얼 디자인을 소개하면서

다음 강좌는 안드로이드 스튜디오 샘플 소스를 하나 선택하여 분석 해보고자 하였습니다.

이번 강좌 안드로이드 스튜디오의 샘플 소스중 하나인 ‘Navigation Drawer Activity’ 를 가지고 살펴보려고 합니다.



강좌를 설명하는 부분에 있어서

제가 잘못알고 설명드리는 부분이 있을 수 있습니다.

그런 부분이 있는경우 알려 주시면 즉시 수정하여 반영하도록 하겠습니다. 





 

우선 신규 프로젝트 생성 시 ‘Navigation Drawer Activity’를 선택 합니다.

 

이 앱에 대해서 간단히 설명 드리면

슬라이드 메뉴가 왼쪽에서 오른쪽으로 열리면서 다른 화면로 쉽게 이동이 가능하게끔 디자인 되어 있습니다

(열리는 모습도 애니메이션 처리 되어 있어서 보기 좋네요)

또한 우측 하단에 둥둥 떠다니는 아이콘이 기본적으로 추가 되어 있으며

이것을 클릭하면 스낵바 라는 새로운 메시지 창이 아래서 살짝 올라오도록 기능이 추가 되어 있습니다.



# 'Navigation Drawer Activity'를 분석해 보자


우선 Android Studio 에서 신규 프로젝트 생성 시 ‘Navigation Drawer Activity’를 선택 합니다.





이 앱에 대해서 간단히 설명 하자면

슬라이드 메뉴가 왼쪽에서 오른쪽으로 열리면서 다른 화면로 쉽게 이동이 가능하게끔 디자인 되어 있습니다

(열리는 모습도 애니메이션 처리 되어 있어서 보기 좋네요)

또한 우측 하단에 둥둥 떠다니는 아이콘이 기본적으로 추가 되어 있으며

이것을 클릭하면 스낵바 라는 새로운 메시지 창이 아래서 살짝 올라오도록 기능이 추가 되어 있습니다



한번씩 실행해 보셨을 거라고 생각하고

소스를 한 번 살펴 볼께요.




activity_main 파일을 보면 (기본 설정이므로 언제나 시작은 activity_main 입니다.) 

우리가 처음 보는 Layoutview가 등장합니다.


소스부분은 생략하도록 하겠습니다.

불필요한 스크롤이 너무 발생하여 오히려 방해가 될것으로 생각됩니다.

기본 템플릿을 수정없이 소스를 분석하는 것이므로 충분히 이해 하실거라고 생각됩니다.




1. DrawerLayout


DrawerLayout 은 메뉴를 왼쪽에서 오른쪽으로(혹은 오른쪽에서 왼쪽으로) 열기 위해 필요한 layout 입니다

또한 그러한 방식을 쓰려면 DrawerLayout를 최상단에 배치 하여야 합니다.

DrawerLayout는 크게 두 가지 부분으로 구성 되어 있다고 생각하시면 됩니다.

본문을 보여줄 부분과 Draw 될 메뉴를 보여주는 부분.

그리고 반드시 순서도 지켜져야 합니다. 본문의 내용이 들어갈 layout을 먼저 기술하고

메뉴 부분의 layout 를 다음에 기술하는 겁니다.

이걸 간단하게 그림으로 표현 하자면 아래와 같습니다.




 


 <DrawerLayout>

   ㄴ<include />

   ㄴ<NavigationView>

 </DrawerLayout>

전체 앱을 DrawerLayout가 감싸고 있고

본문에 들어갈 내용은 별도의 파일로 분리하였습니다.


DrawerLayout의 속성중에 새로운 속성이 2가지 보입니다.

android:fitsSystemWindows tools:openDrawer 입니다.

android:fitsSystemWindows 속성은 뷰가 차지할 수 있는 영역을 

상태바 및 소프트키 영역을 제외한 영역까지 확장해 주는 역할을 합니다.

그런데 이상합니다. 이 속성은 상태바 영역을 제외한 ….’ 이라고 했는데 어플을 실행시켜보면

상태바까지 Drawer가 영향을 미치고 있습니다.








어떤 의미인지는 위 그림을 보시면 금방 이해하셨을거라 생각됩니다.


이 문제를 해결하기 위해 추간된 부분이 있습니다.
values-v21 아래 있는 style.xml 파일을 보시면 됩니다.

여기서 두 가지 속성이 상태바에 영향을 미치도록 설정할 수 있습니다.

android:windowsDrawsSystembarBackgrounds 는 상태바 아래에 다른 뷰가 표시될 수 있도록 합니다

단, 네비게이션바 부분은 제외합니다.(일반적인 경우 네비게이션 바 위에 뷰가 올라옵니다.)

android:statusBarColor 는 상태바 배경색을 지정합니다


그런데그런데….

false 라고 수정했는데도 계속 영향을 미치는 이유는 뭘까요아리송 합니다

제가 아직 수양이 부족한 거 같습니다.

원인을 알게 되면 수정글 올리도록 하겠습니다.



tools:openDrawer Draw 메뉴가 어느 방향에서 열릴지를 설정하는 속성입니다

속성값으로는 gravity를 사용합니다

그런데 2가지 밖에 없네요 start(=left) 혹은 end(=right).

(gravity 값이 기본적으로 OS언어 설정을 따른다는 글을 어디서 본거 같은데 정확히 기억이 안나네요

 영어나 한국어 같이 왼쪽에서 오른쪽으로 쓰는 경우 start left 와 같으며

 아랍어와 같이 오른쪽에서 왼쪽으로 글을 쓰는 경우 start 값이 right 와 같다는 내용이었습니다.)





그럼 이제 include 되어 있는 본문의 내용이 어떻게 구성하였는지 한 번 살펴 볼까요?

본문은 app_bar_main 이라는 파일에 디자인 하였습니다.

여기에 또 새로운 Layout이 보이네요

CoordinatorLayout 입니다.



2. CoordinatorLayout


CoordinatorLayout은 역동적인 상단 메뉴 부분을 만들어 주기 위해 지원되는 Layout 입니다.

아래와 같은 그림 많이 보셨을 거라고 생각합니다.




위 그림과 같이 본문 부분의 스크롤링 상태에 따라 상단의 부분에 대한 액션을 제어하기 위해 필요한 것이 CoordinatorLayout 입니다



하지만 샘플 소스에서는 위와 같이 상단의 이미지가 커졌다 줄어들었다 하는 부분이 구현되어 있지 않습니다. 그 부분은 다음 강좌에서 한 번 시도해 보도록 하겠습니다. 이번 강좌에서는 일단 이런 기능이 지원된다는 것만 알아 두도록 하죠.

CoordinatorLayout 에 대해 조금 더 알아 보겠습니다.

CoordinationLayout도 구조적으로 크게 두 부분으로 나누어 생각 할 수 있습니다.





 


 <CoordinatorLayout>

   ㄴ<AppBarLayout> --> Hearder 부분

      ㄴ<Toolbar />

   ㄴ</AppBarLayout>

   ㄴ<include />        --> Contents 부분

   ㄴ<FloatingActionButton />

 </CoordinatorLayout>

상단의 메뉴 부분과 하단의 내용 부분 입니다.

샘플 소스에서 보면 AppBarLayout 부분이 상단 부분에 해당하고

하단의 본문 부분은 다시 한번 include 하여 디자인을 분리 하였습니다.

 

샘플 소스에서는 스크롤링에 의한 이벤트 구현 부분이 없어서 인지 

AppBarLayoutToolbar에도 중요한 속성은 사용되어 있지 않네요.




그리고 FloatingActionButton 이 있습니다.

위치가 왼쪽 하단에 떠있는데요 위치를 바꾸려면  android:layout_gravity 속성을 수정하시면 됩니다.


 

그럼 이제 CoordinationLayout 안에 include 되어 있는 본문의 내용을 살펴 보겠습니다.


RelativeLayoutTextview로 구성된 본문으로 이미 이전 강좌에서 다뤘던 내용입니다.

여기서 하나 눈여겨 봐야 할 속성이 있습니다.

바로 app:layout_behavior 속성입니다. 매우 중요한 속성입니다.

이 속성에 의해 본문에서 스크롤링이 발생 하였을 때 상단의 AppBarLayout에 대한 컨트롤이 가능해 집니다

본문쪽에서 스크롤이 발생하면 그 이벤트를 AppBarLayout 에 전달해야 하는데 

그 중간 역할을 CoordinatorLayout이 하게 됩니다.

그 이벤트 처리에 대한 것을 app:layout_behavior 에서 담당을 하고 있습니다

그러니 매우 중요한 거 맞죠? ㅎㅎㅎ

 

그럼 이제 마지막으로 DrawerLayoutNavigationView에 대해서 살펴 볼까 합니다.




3. NavigationView


NavigationView 역시 크게 두 부분으로 구분할 수 있습니다.

 


 

 <NavigationView

    app:headerLayout="@layout/nav_header_main"

    app:menu="@menu/activity_main_drawer" />

 

상단의 헤더 부분과 하단의 메뉴 부분 입니다.

NavigationView는 app:headerLayout app:menu 속성으로 헤더와 메뉴 부분으로 나누어 정의하고 있습니다.

 

우선 헤더 부분을 살펴볼께요.


해더 부분은 크게 이미지뷰와 텍스트뷰들로 구성되어 있습니다.

크게 어려운 부분이 없습니다

그래서 패스 패스~~


메뉴 부분을 살펴 보겠습니다.

메뉴 부분은 menu 태그로 큰 틀을 잡고, 안에 groupitem 으로 메뉴를 분리하고 있습니다.

 

메뉴 부분을 조금 더 자세히 보면

item으로 각각의 메뉴 버튼을 생성하는데, 여기서 group 태그로 그룹을 지어 줄 수 있습니다.

그리고 각각의 메뉴 버튼(item)은 서브 메뉴를 가질 수 있습니다.

이럴때는 다시 menu를 사용하여 하위에 item 을 추가합니다.

서브메뉴는 각 item 1번씩만 사용할 수 있다고 합니다.(두번째는 저도 시도를 안해 봤네요 ㅎㅎ;;;)

각각의 메뉴가 눌렸을 때 수행되어야 할 이벤트 처리는  onNavigationItemSelected() 에서 구현하면 됩니다.

메뉴 만들기에 대한 자세한 내용은 아래의 링크를 참조하시면 좋을 것 같습니다.



그런데 전 궁금하더군요.

MainActivity.java 에 보면 메뉴버튼을 클릭 하였을때 onNavigationItemSelected() 메소드를 호출 하라는

구문이 보이지 않았기 때문입니다.

navigaationView와 관련하여서는 

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

아래의 코드가 전부입니다.

어디서도 연결 고리를 찾을 수가 없는데요....

어떻게 찾아야 할까요..?

이때 Ctrl+마우스 왼쪽 클릭을 활용해 내용을 찾을 수 있습니다.


이전 강좌에서 한 번 설명드렸는데요.

기본 제공되는 API의 구현부분에 대해 상세히 알고 싶을때

해당 메소드를 Ctrl과 함께 마우스 오른쪽 클릭하면 메소드가 구현되어 있는 부분으로 이동할 수 있는 팁 입니다.

(이부분은 Did you know...? 에도 나오더군요. 나중에 강좌로 따로 만들어 볼까 합니다.)


위의 onNavigationItemSelected()는 구현 부분이므로 호출하는 쪽을 찾아야 합니다.

단서라고는 위의 소스 2둘뿐입니다.


객체를 생성하는 첫줄을 빼고, 두번째 줄 부터 시작해 봅니다.

우선 setNavigationItemSelectedListener 부분에서 Ctrl+마우스 왼쪽 클릭을 합니다.

그러면 NavigationView.java 파일이 열리면서, setNavigationItemSelectedListener 부분을 찾아 갑니다.

/**
* Set a listener that will be notified when a menu item is clicked.
*
* @param listener The listener to notify
*/
public void setNavigationItemSelectedListener(OnNavigationItemSelectedListener listener) {
mListener = listener;
}

위와 같이 구현되어 있습니다.

인자 값으로 OnNavigationItemSelectedListener 값을 받습니다. 

그럼 이제 OnNavigationItemSelectedListener 부분의 구현 부분을 찾아가 봅니다.

/**
* Listener for handling events on navigation items.
*/
public interface OnNavigationItemSelectedListener {

/**
* Called when an item in the navigation menu is selected.
*
* @param item The selected item
*
* @return true to display the item as the selected item
*/
public boolean onNavigationItemSelected(MenuItem item);
}

같은 파일의 하단에 위와 같이 구현되어 있습니다.

짠~ 찾았습니다. 

'public boolean OnNavigationItemSelected(MenuItem item)' 이 있네요.



마지막으로 다른 디자인 부분과 마찬가지로 메뉴도 코드로 구현하여 만들 수 있습니다

하지만 메뉴는 리소스에서 작업하는 것이 좋을거 같습니다.

코드로 만들어 생성하는 것보다 훨씬 작업이 간편하고 

조금이나마 시스템 부하를 줄일 수 있기 때문입니다.





반응형