임종뚱 2019. 12. 26. 13:41

오늘은 DrawerLayout을 통해 네비게이션 메뉴 바 를 커스텀 할 수 있도록 만들어 볼 것이다!.

 

Drawer라는 단어가 뜻하는 "서랍"이 열리고 닫히는 것처럼, DrawerLayout "평소에는 화면의 한쪽에 숨겨져 있다가 사용자가 액션을 취하면 화면에 나타나는 기능을 만들 수 있게 해주는 레이아웃"입니다.

 

하지만 DrawerLayout에 대한 설명을 보고, DrawerLayout 자체가 화면에 나타나거나 사라지는 동작을 수행하는 것으로 오해하면 안됩니다. DrawerLayout에 추가된 자식(Children)이 DrawerLayout의 영역 안에서 "Drawer(서랍)"와 같은 동작을 수행하도록 만들어주는 것이죠.

 

그리고 DrawerLayout에 추가된 모든 자식(Children)들이 Drawer로 동작하는 것이 아니라는 사실에도 주의해야 합니다. 자식(Children)들 중 layout_gravity 속성 값을 가지지 않은 자식(Child)은 기본적으로 표시되는 주화면으로 취급되고, layout_gravity 속성 값을 가진 자식(Child)만이 Drawer로써 동작하는 것이죠. 또한 Drawer가 어느 방향에서 열릴지는 layout_gravity에 지정된 값(left or right)에 의해 결정됩니다.

 

 

 

메인 액티비티 레이아웃을 설정하자!

전체 레이아웃을 DrawerLayout을 설정하고 id값을 drawer_layout으로 설정해주며 메뉴 버튼을 만들어 버튼 클릭 시 메뉴 열기 이벤트를 만들 것 이다

 

메뉴 화면 xml을 따로 만들어주어 간단하게 레이아웃을 설정하였다

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:id="@+id/drawer_layout">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/brn_open"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="열려라 참깨">
        </Button>

    </LinearLayout>

    
</androidx.drawerlayout.widget.DrawerLayout>

이 메인 화면에서 메뉴 바를 만들어 줄 것이다.

 

그 다음에 네비게이션 메뉴 바 레이아웃을 만들어 설정해준다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#7181D6"
    android:id="@+id/drawer">

    <Button
        android:layout_margin="10dp"
        android:id="@+id/btn_close"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="메뉴 닫기"/>

    <TextView
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="종드로이드 메뉴"
        android:gravity="center"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="#3BB2E7">

        <TextView
            android:layout_margin="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="테스트 메뉴"
            android:gravity="center"/>
    </LinearLayout>

</LinearLayout>

메인 화면에 이 activity_drawer xml을 보여주는 것으로 메인 화면 DrawerLayout 끝나기 전에

<include layout = "@layout/activity_drawer"/> //메인화면에 포함시켜준다
</androidx.drawerlayout.widget.DrawerLayout>

 

그러면 이렇게 파란 점선들로 포함 되어 있다는 것을 확인할 수 있다

 

이제 MainActivity.java로 가서 이벤트 처리를 해줄 것이다.

 

drawerLayout 과 drawer id 값을 넣어주고 버튼 btn_open에도 마찬가지로 넣어준다.

 

btn_open 버튼 클릭 시 drawerLayout.openDrawer(drawer); 통해 activity_drawer xml이 드로우 된다

반대로 btn_close 클릭 시 닫아주는 .closeDrawers(); 통해 닫아준다

 

그 다음 drawerLayout.setDrawerListener(listener); 을 설정해 주어야 하는데 여기서 listener를 만들어줘야 에러가 안 난다.

 

onCreate 생명주기 밖에다가 설정 해주며

 

각 메서드는 액션에서 상태값을 가져오는 것이다

DrawerLayout.DrawerListener listener = new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {

            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {

            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {

            }

            @Override
            public void onDrawerStateChanged(int newState) {

            }
        };

 

View의 .setOnTouchListener을 설정해주면 터치로 메뉴를 열고 닫을 수 가 있다

 

실행하면 열기버튼 클릭 시 열리고 닫기 버튼을 누르면 닫혀지고 터치또한 잘 작동한다!!