2016년 8월 1일 월요일

Android Studio - 간단한 Navigation Drawer 적용


[Navigation Drawer]

1. android design support 라이브러리 활용 (Graddle 에 dependency 추가 필요 함)
프로젝트 익스플로러에서 '모듈 우클릭' -> 'open module setting' -> 'dependency 탭 선택' -> '우측의 + 버튼 클릭'

  library : 이미 다운 받아진 구글의 라이브러리
  file : 개발자가 다운 받은 임의의 jar 파일
  module : 현재 개발중인 다른 모듈의 라이브러리

com.android.support:design:24.1.1 추가

Graddle에 추가된 것 확인

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'    
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:24.1.1'
}


2. activity_main.xml 에다가 navigation tag 추가 (최상위 루트에다가 추가)
최상위와 최 하위에다가 아래 추가

<android.support.v4.widget.DrawerLayout>
블라블라~~
</android.support.v4.widget.DrawerLayout>

ALT+CTRL+L 단축키로 인덴테이션 맞추고, 루트태그 속성을 아래와 같이 카피해다가 붙인다.

<android.support.v4.widget.DrawerLayout

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >

(fitsSystemWindows : 시스템 상태바 가리지 않게 하기 위해서)

근데 이렇게 하면 에러가 나게 된다.
사용하는 view가 표준라이브러리의 view라면 그곳의 속성도 표준속성이다.
표준속성은 android라는 이름의 namespace로 등록되어있음
  => xmlns:android="http://schemas.android.com/apk/res/android"
But, 우리가 쓰고자 하는 NavigationView는 표준라이브러리가 아니다.
'android:' 을 사용할 수가 없다.
그래서 별도의 namespace를 등록해서 적용해야 한다.

xmlns:app="http://schemas.android.com/apk/res-auto"

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    >


Navigation view를 기존 layout 밑에다가 추가 해 줌.

<!-- navigation drawer에 의해서 나오는 부분 --><android.support.design.widget.NavigationView

    android:id="@+id/main_drawer_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/navigation_header"
    app:menu="@menu/main_drawer">
</android.support.design.widget.NavigationView>


3. navigation header xml, navigation menu xml 세팅

layout/navigation_header.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="172dp"
    android:background="#FF0000">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="i am header"
        android:textColor="#FFFFFF"
        android:gravity="bottom"
        android:textSize="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginBottom="20dp"
        />
</LinearLayout>

menu/main_drawer.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/navigation_item_1"
            android:icon="@android:drawable/ic_menu_manage"
            android:title="Menu1"/>
        <item
            android:id="@+id/navigation_item_2"
            android:icon="@android:drawable/ic_menu_search"
            android:title="menu2"/>
    </group>
</menu>


4. MainActivity에 추가 및 이벤트 적용

컨트롤을 하기 위해서 변수를 선언

DrawerLayout drawer;
ActionBarDrawerToggle toggle;
boolean isDrawerOpened;

onCreate 함수안에 아래 추가

// navigation drawerdrawer = (DrawerLayout) findViewById(R.id.drawer);
// 생성자에 인자로 들어간 문자열은 화면 출력 문자열이 아니라// 상태 표현을 위한 접근성 차원에서 제공하는 문자열toggle = new ActionBarDrawerToggle(this, drawer,
        R.string.drawer_open,
        R.string.drawer_close) {
    // 이벤트 추가, 필수는 아님
    @Override    public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        isDrawerOpened = true;
    }

    @Override    public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        isDrawerOpened = false;
    }
};
drawer.addDrawerListener(toggle);   // 이벤트 핸들러인 toggle을 적용
// 액션바 아이콘을 업 네비게이션 형태로 표시
getSupportActionBar().setDisplayHomeAsUpEnabled(true); NavigationView navigationView = (NavigationView) findViewById(R.id.main_drawer_view); navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { // navigation view의 항목 선택 시 이벤트 콜백함수 @Override public boolean onNavigationItemSelected(MenuItem item) { Log.d("mulcam", "navigation view: " + item.getItemId()); return false; } }
);

그리고 잔여 이벤트 처리를 위해서

@Overridepublic void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
    super.onPostCreate(savedInstanceState, persistentState);
    toggle.syncState();
}

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {
    if(toggle.onOptionsItemSelected(item)){
        // 발생한 메뉴 이벤트가 navigation view 에서의 이벤트인 경우 후속처리 x        return true;
    }
    return super.onOptionsItemSelected(item);
}

// navigation drawer가 화면에 보이고있다.// 그 상황에서 유저가 back 버튼을 누르면// back 버튼 이벤트를 제어해서 drawer를 닫아준다.// 모든 key event onKeyDown(){}의 함수를 사용하는데// back button만을 제어할 목적이라면 onBackPressed 함수를 이용하면 편하다@Overridepublic void onBackPressed() {
    if(isDrawerOpened){
        drawer.closeDrawers();
    }else{
        super.onBackPressed();
    }
}


댓글 없음:

댓글 쓰기