본문 바로가기

안드로이드 스튜디오

#7. 내비게이션 메뉴 커스텀 예시

안드로이드 스튜디오

- 내비게이션 메뉴 커스텀 -



이전에 다뤘던 내비게이션 메뉴를 이번에는 직접 커스텀을 해보는 시간을 가져보자

시작은 New Project를 만들고 Empty Activity 틀에서 시작할 것이다.


프로젝트를 새로 만든 다음 activity_main.xml 파일로 들어가서 레이아웃을 DrawerLayout으로 변경해 줄 것이다.

ConstraintLayout 으로 되어 있는 부분을 다음과 같이 변경

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"

그 다음 기본으로 만들어지는 TextView는 지워준 다음 DrawerLayout 안에 LinearLayout을 추가해 줄거다.

<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

//리니어 레이아웃 생성!
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

생성한 레이아웃 안에 버튼을 만들어보자

이 버튼을 누르면 옆에서 메뉴창이 나오는 형식으로 만들어볼 것이다.

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

<Button
android:id="@+id/btn_open"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="버튼이에요"/>

</LinearLayout>

이런 식으로 width = "match_parent" / height = "wrap_content" 로 설정해주면 그림과 같이 버튼이 생성된다.


지금까지 만들어본 건 MainActivity, 즉 메인화면을 구성한 것이다.

그럼 메인화면을 제외한 다른 화면을 하나 더 만들것인데 이전에 화면만들기 한 것과 비슷하게

app->res->layout 폴더를 우클릭->New->Layout Resource File 클릭해서 새로운 파일 생성!

이름을 activity_drawer 로 설정한 후 Ok 클릭으로 생성!

이제 이곳이 슬라이드메뉴 화면이 될 것이다.


곧바로 Layout을 변경 해 줄건데 LinearLayout으로 변경해 준다.

그럼 자동적으로 layout_height, layout_width 의 값이 "match_parent" 로 빈 공간 없이 꽉 채우도록 되어 있는데

보통 어플들의 메뉴바를 보면 화면의 약 2/3부분에만 메뉴바가 펼쳐지는 것을 볼 수 있다.

그러한 점을 위해 width 부분을 240dp로 설정해 줄 것이다.


우선 코드를 보면서 설명하자면

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="start"
android:background="#c8f5ab">

간단히 설명을 하자면

layout_gravity="start" 이 부분은 해당 화면의 위치를 시작점에 맞춰주는 것이고

background는 배경색을 지정해주는 기능을 한다.

실제로 배경색을 지정하는 방법을 사진으로 설명해보면,


동그라미친 부분을 더블클릭하면 아래 choose color 창이 뜬다.


이곳에서 마음에 드는 색을 골라 쓰면 된다. 아래에서 투명도도 조절 가능하다.


이렇게 메뉴의 기본 판을 만들었으니 안에 들어갈 선택지(버튼)들을 만들어보자.




LinearLayout 설정 지정해준 구문 아래에 버튼 생성

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

그럼 위와 같이 버튼이 생성되는 것을 볼 수 있다.


그리고 LinearLayout 만으로도 버튼과 비슷하게 구분을 할 수 있는데 그 예시를 보여주자면

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

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#21ce38">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Example Menu"/>
</LinearLayout>

앞에서 만든 버튼구문 아래에 LinearLayout을 만들어 준 다음 그 안에 TextView를 넣어준 모양이다.

여기서 리니어레이아웃 설정 구문에서 height="wrap_content" 이 부분은 이 리니어레이아웃 안의 TextView를

감쌀 것이다! 이런 의미여서 <TextView ~ 부분을 쓰지 않으면 프리뷰에서 아무것도 나오지 않을 것이다.


위 그림처럼 나타나게 된다.


그런데 만들어진 메뉴를 보면 버튼과 버튼 사이가 너무 딱 붙어있고 버튼이 메뉴창에 꽉 차서 보기 싫다.

이러한 점을 보완하기 위해 LinearLayout 설정 내부에서 margin이라는 기능을 써 줄 것이다.

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
// margin 값 설정!
android:layout_margin="10dp"
android:orientation="vertical"
android:background="#21ce38">

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


이제 좀 버튼다워진 것을 볼 수 있다.


그럼 만들어 준 버튼들의 기능을 한번 부여해 보자


MainActivity.java 파일로 들어가서 다음과 같이 DrawerLayout과 View를 선언

public class MainActivity extends AppCompatActivity {

private DrawerLayout drawerLayout;
private View drawerView;

그다음 activity_main.xml 파일의 DrawerLayout 전체에다 아이디를 만들어 줄 것이다.

<?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"
tools:context=".MainActivity">

이 DrawerLayout 안에 구문들의 마지막부분에 include 라는것을 해줄것이다.

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

이 구문의 의미는 우리가 만들었던 다른 화면인 activity_drawer.xml 파일을 activity_main.xml 파일에 추가시키는 

것이다.

그러면 프리뷰에 이렇게 파란색 테두리가 보일 것이다. (그러면 성공)



DrawerLayout 아이디를 만들어줬으니 같이 선언한 View의 아이디도 만들어줘야 한다. (메뉴화면 아이디)

activity_drawer.xml 파일에서 전체 레이아웃인 LinearLayout 설정 구문에 id값을 넣어준다.

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

다시 MainActivity.java 로 들어가서 onCreate 메소드 안에 다음과 같이 입력한다.

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
drawerView = (View)findViewById(R.id.drawer);

}

계속해서 Main화면에 있던 btn_open 버튼을 선언 및 기능 추가를 해주자면

Button btn_open = (Button)findViewById(R.id.btn_open);
btn_open.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
         drawerLayout.openDrawer(drawerView);
      }
});

btn_open 버튼을 누르면 drawerLayout 레이아웃에서 drawerView가 열린다. 이런 기능을 추가해 준 모습이다.

< 햇갈릴 수 있는데 drawerLayout은 Main화면이고 drawerView는 메뉴화면이다. 아이디값 확인해보기! />


그 다음 MainActivity.java 파일에서 onCreate매소드의 밖에다

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

}

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

}

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

}

@Override
public void onDrawerStateChanged(int i) {

}
};

DrawerListener 라는 것을 정의해 줄건데

DrawerLayout.DrawerListener listener = new DrawerLayout.DrawerListener 까지 치면 자동으로 아래 있는

메소드들이 생성된다.

이 리스너들은 슬라이드메뉴가 특정 조건일 때 특정 액션을 넣어주기 위해 쓰이는데

onDrawerSlide : 슬라이드 했을 때 호출

onDrawerOpened : Drawer가 오픈된 상황일 때 호출

onDrawerClosed : Drawer가 닫힌 상황일 때 호출

onDrawerStateChanged : 특정 상태가 변경될 때 호출


그 다음 다시 onCreate 안에다 listener를 선언해 줄 것이다.

리스너는 선언해놓는 것이 좋기 때문에 일단 만드는 방법을 설명한 것이다.

drawerLayout.setDrawerListener(listener);

바로 아래에 다음과 같이 setOnTouchListener를 구현해 줄 것이다.

drawerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});

setOnTouchListener는 우리가 폰화면을 터치하고 손을 움직이고 손을 떼는 순간까지 모두 실행되는 함수이다.

< setOnClickListener : 화면을 눌렀다 뗄 때 실행되는 함수 />

기본적으로 (new View.OnTouchListener 까지 쓰고 자동으로 필요한 메소드를 import하면

return 값이 false; 가 되어있는 것을 확인할 수 있다.

저 값을 True로 바꿔야 우리가 원하는 기능을 해줄 수 있다.

return true;

마지막으로 우리가 앞에 메뉴에 만들었던 btn_close 버튼으로 메뉴화면을 닫는 기능까지 만들어주자.

onCreate 매소드 안에서 적어준다.

Button btn_close = (Button)findViewById(R.id.btn_close);
btn_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerLayout.closeDrawers();
}
});

여기서 drawerLayout.closeDrawer(); 가 있고 closDrawers(); 가 있는데

closeDrawer(int drawerLayoutID, int gravity); 매개변수가 필요, 매개변수로 받은 뷰를 닫는 역할

closeDrawers() : 현재 열려있는 모든 사이드메뉴(DrawerView)를 닫는 역할

그래서 closeDrawers(); 를 써줘야 한다.



이렇게 간단하게 내비게이션메뉴를 커스텀 해 보았는데 이해는 되지만 아직 여러 기능을 추가하려면

그 기능들을 어떻게 추가하는가에 대한 공부가 많이 필요한 것 같다.