🎨 메뉴
- 2가지 종류: 옵션 메뉴, 컨텍스트 메뉴

- 메뉴 버튼 클릭 시 (주로) 하단에 메뉴가 촤라락 펼쳐짐
- 이 옵션 메뉴를 생성하는 방법에는 2가지가 있다.
- 메뉴 XML 파일 생성 후 Java에서 호출하는 방법
- 메뉴는 대부분 항목이 고정되어 있으므로 XML 사용
- 메뉴 XML 파일을 이용하면 앱을 다른 나라 언어로 변경할 때 Java 코드를 건드리지 않아도 되므로 효율적임
- Java만 이용하는 방법
먼저 XML과 Java를 사용하는 방법에 대해 알아보자.
⭐ XML+Java로 옵션 메뉴 만드는 틀
- 메뉴 XML을 사용하는 방법

- 메뉴 XML 파일의 형식

- onCreateOptionsMenu( ) 메소드 기본 형식

- onOptionsItemSelected( ) 메소드 기본 형식
- 메뉴를 선택했을 때 어떤 동작을 할 것인지 정의함
- 메뉴는 항목이 여러 개 나오기 때문에 보통 switch()~case문을 사용함

🍪 인플레이터(Inflater)
- '부풀리는 장치' or '자전거 등의 공기 펌프'라는 뜻
- 즉, 풍선에 바람을 넣어서 실제 객체로 만들어 사용한다는 의미 (풍선은 바람을 넣기 전에는 별 의미가 없다.)
- 안드로이드에서 사용되는 인플레이터를 이와 같이 생각하면, 정적으로 존재하는 XML 파일(풍선)을 Java 코드에서 접근하여(바람을 넣어) 실제 객체로 만들어서 사용하는 것이라고 볼 수 있다.
- 메뉴 인플레이터(MenuInflater) 객체는 메뉴 XML 파일을 Java 코드에서 가져와 사용하는 것이고,
레이아웃 인플레이터(LayoutInflater)는 레이아웃 XML 파일을 Java 코드에서 가져와 사용하는 것이다.
✍🏻 배경색 바꾸기 앱 만들기 - XML & Java

1. activity_main.xml 수정하기 
3. 메뉴 xml 생성하기 
4. 메뉴 xml 편집하기 
- 1,26행: 메뉴의 시작과 끝을 나타낸다. menu 폴더에 XML 파일을 만들면 자동으로 생성된다.
- 3~6행: 메뉴 항목을 1개 추가한다. id는 Java 코드에서 접근할 때 사용하며, 타이틀은 화면에 보이는 제목이다.
- 15~24행: 메뉴 항목 안에 다시
<menu>가 있으므로 이 부분을 클릭하면 서브 메뉴가 나타난다. (menu 중첩)
- 16~23행: 서브 메뉴의 메뉴 항목이 나열되어 있다.
5. Java 코드 작성 및 수정 
- 3~4행: 레이아웃과 버튼에 대응할 전역변수 2개를 선언한다.
- 11~12행: 메인함수 onCreate() 안에서 위젯 변수 2개에 위젯을 대입한다.
- 8,11행: 상위 클래스의 생성자를 실행한다. 자동 완성된 부분에서 return문만 삭제하고 마지막 행에 return true를 추가한다.
- 9,10행: 메뉴 인플레이터를 생성하고 앞에서 작성한 메뉴 XML 파일(
menu1.xml=R.menu.menu1)을 등록한다.
7. Java 코드 수정 - 메뉴 클릭 시 동작하는 onOptionsItemSelected( ) 메소드 코딩 
- 8~19행:
item.getItemId로 어떤 항목을 선택했는지 구한 후 switch()~case문으로 각 항목마다 실행할 내용을 코딩한다.
- 9~11행: 선택한 항목이 '배경색(빨강)'
itemRed이면 레이아웃의 배경색을 빨강으로 설정한다.
- 12행: 9~11행과 거의 동일한 내용을 itemGreen, itemBlue에 대해서 반복한다.
- 14~17행: 선택된 메뉴가 서브 항목의 아이디라면 버튼을 회전시키거나 버튼의 X축을 2배 확대한다.
서브 항목은 menu1.xml 화면에 나타나는 모양으로 구분된 것일뿐
Java 코드에서는 메인 항목, 서브 항목을 구분할 필요없이 case문의 아이디로만 구분한다.
✍🏻 배경색 바꾸기 앱 만들기 - Only Java 
-
5~7행: menu.add() 함수로 직접 메뉴 "항목"을 추가한다.
menu.add(그룹아이디, 항목아이디, 순번, 제목)
-
메인 항목과 서브 항목은 메뉴 객체(menu, sMenu)만 다를 뿐,
항목아이디는 구분없이 그대로 이어진다.(1,2,3,4,5)
-
Why?? switch()~case 문에서 이 항목아이디를 가지고 찾을 것이기 때문!
-
9~11행: 9행에서 SubMenu 클래스로 서브메뉴를 만들고
10행과 11행에서 서브메뉴에 항목을 추가했다.
-
19행: 각 case문이 메뉴에 지정한 항목 아이디와 일치하도록 변경한다.
- 일반적으로 위젯을 롱클릭했을 때 제목과 함께 화면 중앙에 출력됨
- Windows의 팝업창과 유사함
- 여러 개 위젯에 메뉴를 설정 가능 (
메뉴 수 = 메뉴 XML 파일 수)
⭐ XML+Java로 컨텍스트 메뉴 만드는 틀
-
컨텍스트 메뉴 설정 순서 
🎨 토스트(Toast)
- 화면에 잠깐 나타났다 사라지는 메세지
- 프로그래머가 디버깅 용도로 사용하기에도 적당
토스트의 일반적인 형태 
- context : 출력할 화면, 보통
this를 쓴다.
예외적으로 버튼을 클릭했을 때 내부 클래스에서 토스트를 출력하기 위해 액티비티명.this를 사용한다.
- message : 출력할 메세지
- duration : 화면에 나타나는 (지속)시간,
Toast.LENGTH_LONG orToast.LENGTH_SHORT
토스트 위치 변경하기
- 토스트는 기본적으로 화면의 중앙 하단 부근에 나타나는데,
setGravity() 메서드를 사용하면 위치를 변경할 수 있다. 
- gravity : 화면의 위, 중앙, 아래 등을 지정
- xOffset, yOffset : 떨어진 거리
✍🏻 토스트 위치 바꾸어 출력하기 

-
10~11행: 토스트메세지를 만든다.
현재 액티비티에 '토스트 연습'을 출력하고, 이 메세지를 짧은 시간동안 보여준다.
-
13~16행: 임의의 위치를 구한다.
현재 안드로이드폰의 디스플레이를 getSystemService() 메소드로 구한 후,
getWidth()로 화면 너비를, getHeight로 화면 높이를 돌려준다.
Math.random()은 0~1 사이의 임의의 수를 구한다.
결국 xOffset은 0~화면너비 범위에서 임의의 수를,
yOffset은 0~화면높이 범위에서 임의의 수를 구하는 것이다.
-
18~19행: setGravity() 메서드로
화면 상단(Gravity.TOP) 왼쪽(Gravity.LEFT)으로부터
각각 xOffset, yOffset만큼 떨어진 곳에 토스트메세지를 출력한다.
🎨 대화상자(dialog)
- 화면에 메세지를 나타낸 후,
확인이나 취소같은 사용자의 선택을 받아들이는 경우에 사용한다.
- 토스트보다 좀 더 강력한 메세지
- 사용자에게 중요한 사항을 알려준 후, 사용자가 어떤 선택을 하게 하는 것이 목적이다.
🧵 기본 대화상자
- AlertDialog.Builder 클래스 사용

✍🏻 버튼없는 기본형 대화상자 만들기 
- 버튼이 없는 기본형이므로, 키패드의 돌아가기 버튼을 클릭하면 대화상자가 닫힌다.
- 8행: AlertDialog.Builder 클래스를 사용해 대화상자를 생성한다.
현재 내부 클래스 안이므로 액티비티명.this로 컨텍스트를 지정한다.
- 9~11행: 제목, 메세지 내용, 아이콘을 설정한다.
- 12행: 대화상자를 화면에 출력한다.
✍🏻 버튼 1개인 대화상자 만들기 
- 위의 코드에
dlg.setPositiveButton()만 추가하면 된다.
setPositiveButton("문자열", 리스너)
현재 리스너 부분에 null을 입력했으므로
<확인>을 클릭해도 대화상자만 닫힐 뿐 아무 동작도 일어나지 않는다.
특정 동작을 하도록 만드려면 7행을 다음과 같이 수정한다. 
- 만약, 취소버튼도 넣고싶다면
dlg.setNegativeButton()을 추가하면 된다.
🧵 목록 대화상자
- 대화상자에 리스트 형태의 목록을 출력하고 그중 하나를 선택하게 할 수 있다.
- 조금 복잡해 보일 수도 있으나 비슷한 형태로 매번 사용되니 코드를 통째로 기억하자!
✍🏻 기본형 목록 대화상자 
- 기본형 목록 대화상자는 선택과 동시에 창이 닫힌다.
- 4행: 출력할 항목의 문자열 배열(versionArray)을 만들었다. 내부 클래스 안에서 사용될 것이므로 final을 붙였다.
- 8~13행:
setItems(문자열 배열, 리스너) 메소드를 사용했다.
9행과 10행을 보면 리스너는 클릭할 경우에 동작하는 OnClickListner()를 사용했다.
10행의 onClick() 메소드 파라미터중 which는 몇 번째 항목을 선택했는지를 알려준다.
그러므로 11행에서 버튼의 글자를 배열(versionArray)의 which번째 문자로 변경했다.
✍🏻 라디오버튼 목록 대화상자 
- 라디오버튼 목록 대화상자는 선택해도 대화상자가 닫히지 않는다.
setSingleChoiceItems(문자열 배열, 초기 선택 인덱스, 리스너)
✍🏻 체크박스 목록 대화상자 
- 여러 개를 동시에 선택할 수 있는 대화상자이다.
setMultiChoiceItems(문자열 배열, 체크유무 확인하는 배열, 리스너)
- 5행: 각 항목이 체크되었는지를 boolean 배열로 만들었다. 이 배열명을 9행에 입력해야한다.
- 9~15행:
setMultiChoiceItems()의 두번째 파라미터(checkArray)는 문자열 배열과 개수가 같은 boolean 배열이어야 한다. 그래야 처음 화면이 나올 때 항목의 체크여부를 표시할 수 있다.
10행의 리스너는 setMultiChoiceClickLister()를 사용한다.
파라미터로는 선택된 항목의 인덱스인 which와 해당항목의 체크여부인 isChecked가 있다.