[안드로이드 프로그래밍] Menu

PUJIN·2023년 6월 17일
0

android programming

목록 보기
10/26
post-thumbnail

📌 Option Menu

action bar에 나타나는 메뉴

  • 화면 1개당 하나씩 가질 수 있다.
  • 현재 화면의 메인 메뉴

기본 세팅

res > values > themes > themes.xml

  • NoActionBar : action bar 화면 표시 X (기본)
    • action bar 거의 사용 X → tool bar 사용
<style name="Base.Theme.Android37_EX01" parent="Theme.Material3.DayNight.NoActionBar">
  • NoActionBar 아닌 다른 항목으로 설정해야 action bar가 화면에 표시된다.
<style name="Base.Theme.Android37_EX01" parent="Theme.Material3.Light">

* ActionBar 보이지 않게 설정 : NoActionBar의 기본 설정

<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

주요 메서드

  • OnCreateOptionsMenu : 옵션 메뉴를 구성하는 메서드 (옵션 메뉴 활성화)
    • menu: Menu? : 최상단 메뉴 객체
  • xml 파일을 통한 메뉴 생성
    • 메뉴 : ID로 구분
    • menuInflater : menu.xml 파일로 만들 수 있는 것
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
	menuInflater.inflate(R.menu.main_menu, menu)
}
  • 코드를 통한 메뉴 구성
    • 메뉴가 때에 따라 변할 때 사용 (실행할 때 변하는 경우), 저장된 값에 따라 변하는 경우 사용
    • 메뉴 : 정수로 구분
    • groupId & order = Menu.NONE : 작성한 순서대로 출력
    • itemId : 메뉴를 구분하기 위한 값 (FIRST = 1)
    • menu?.함수() : null 값이 포함되어 있으면 코드 호출 X
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
	menu?.add(Menu.NONE, Menu.FIRST, Menu.NONE, "코드 메뉴 1")
	menu?.add(Menu.NONE, Menu.FIRST + 1, Menu.NONE, "코드 메뉴 2")
	// 하위 메뉴 구성
	val subMenu = menu?.addSubMenu("코드 메뉴 3")
	subMenu?.add(Menu.NONE, Menu.FIRST + 2, Menu.NONE, "하위 메뉴 3-1")
	subMenu?.add(Menu.NONE, Menu.FIRST + 3, Menu.NONE, "하위 메뉴 3-2")
	menu?.add(Menu.NONE, Menu.FIRST + 4, Menu.NONE, "코드 메뉴 4")
	return super.onCreateOptionsMenu(menu)
}
  • onOptionsItemSelected : 옵션 메뉴에서 메뉴 항목을 선택하면 호출되는 메서드
    • 매개변수(item: MenuItem) : 사용자가 선택한 메뉴 항목 객체
  • xml 파일로 메뉴 구성한 경우
    • 메뉴 항목의 ID로 분기
override fun onOptionsItemSelected(item: MenuItem): Boolean {
	activityMainBinding.run {
    	when(item.itemId) {
        	R.id.menu_item1 -> textView.text = "메뉴 항목1 선택"
            R.id.menu_item2 -> textView.text = "메뉴 항목2 선택"
            R.id.menu_item31 -> textView.text = "하위 메뉴 3-1 선택"
            R.id.menu_item32 -> textView.text = "하위 메뉴 3-2 선택"
            R.id.menu_item4 -> textView.text = "메뉴 항목4 선택"
		}
	}
    return super.onOptionsItemSelected(item)
}
  • 코드로 메뉴 구성한 경우
    • 설정한 정수 값으로 분기
override fun onOptionsItemSelected(item: MenuItem): Boolean {
	activityMainBinding.run {
    	when (item.itemId) {
			Menu.FIRST -> textView.text = "코드 메뉴1 선택"
            Menu.FIRST + 1 -> textView.text = "코드 메뉴2 선택"
            Menu.FIRST + 2 -> textView.text = "코드 하위 메뉴 3-1 선택"
            Menu.FIRST + 3 -> textView.text = "코드 하위 메뉴 3-2 선택"
            Menu.FIRST + 4 -> textView.text = "코드 메뉴4 선택"
		}
	}
    return super.onOptionsItemSelected(item)
}


주요 속성

  • showAsAction
    • None : ActionBar에 표시 X, option menu에 표시 (기본)
    • Always : 무조건 ActionBar에 표시
    • ifRoom : 공간있는 경우 ActionBar에 표시
  • Icon : ActionBar에 표시할 아이콘 지정
    • option menu에는 아이콘 표시 X
    • action bar에 표시
  • withText : 공간있는 경우 아이콘과 문자열 함께 표시

* action bar에 나타날 경우 : option menu와 똑같이 구현



📌 Popup Menu

원할 때 원하는 곳에 띄울 수 있는 메뉴


  1. 팝업 메뉴 객체 생성
    * 버튼을 눌렀을 때 textView에 popup menu가 나타나는 경우
    → button의 setOnClickListener 안에서 실행
// textView에 menu가 나타나게 하는 구성
val pop = PopupMenu(this@MainActivity, textView)
  1. 팝업 메뉴 구성
menuInflater.inflate(R.menu.popup_menu, pop.menu)
  1. 팝업 메뉴 보여주기
pop.show()

주요 이벤트

  • setOnMenuItemClickListener : 팝업 메뉴의 항목을 클릭했을 때 동작하는 리스너
    • return 값 : true & false 차이 X
pop.setOnMenuItemClickListener {
	when (it.itemId) {
		R.id.popup1 -> textView.text = "팝업 메뉴 1 선택"
		R.id.popup2 -> textView.text = "팝업 메뉴 2 선택"
		R.id.popup3 -> textView.text = "팝업 메뉴 3 선택"
	}
	true
}



📌 Context Menu

화면에 배치된 View에 설정하는 메뉴

  • 메뉴가 설정된 View를 길게 누르면 메뉴 확인 가능

주요 메서드

  • registerForContext : context menu를 등록하는 메서드
    • 매개변수로 설정한 view 객체에 메뉴 설정
    • 메뉴를 등록하고 싶은 모든 view에 모두 설정
registerForContextMenu(textView)
  • onCreateContextMenu : context 메뉴를 구성하는 메서드 (context 메뉴 활성화)
    • context menu가 설정된 view의 아이디로 분기
    • setHeaderTitle : 메뉴 제목 설정
  • textView에 context menu 설정
override fun onCreateContextMenu(
	menu: ContextMenu?,
	v: View?,
	menuInfo: ContextMenu.ContextMenuInfo?
) {
	super.onCreateContextMenu(menu, v, menuInfo)
	if (v != null) {
    	when (v.id) {
			R.id.textView -> {
				menu?.setHeaderTitle("textView 메뉴")
				menuInflater.inflate(R.menu.context_menu, menu);
                // Fragment인 경우 해당 Fragment가 포함된 activity 이용
//				mainactivity.menuInflater.inflate(R.menu.context_menu, menu);
            }
        }
    }
}
  • listView에 context menu 설정
    • menuInfo : 해당 매개변수로 들어오는 객체로 사용자가 길게 누른 항목이 listView의 몇 번째 항목인지 파악 → 가장 중요
override fun onCreateContextMenu(
	menu: ContextMenu?,
	v: View?,
	menuInfo: ContextMenu.ContextMenuInfo?
) {
	super.onCreateContextMenu(menu, v, menuInfo)
	if (v != null) {
    	when (v.id) {
			R.id.listView -> {
            	val info = menuInfo as AdapterView.AdapterContextMenuInfo
				menu?.setHeaderTitle("${dataList[info.position]}의 메뉴")
				menuInflater.inflate(R.menu.list_menu, menu)
            }
        }
    }
}
  • onContextItemSelected : context menu의 항목을 선택하면 호출되는 메서드
    • 서로 다른 뷰의 context menu라고 해도 메뉴의 ID는 다르게 구성
  • textView에 context menu 설정
override fun onContextItemSelected(item: MenuItem): Boolean {
	when (item.itemId) {
		R.id.context1 -> activityMainBinding.textView.text = "텍스트뷰 - 메뉴1"
		R.id.context2 -> activityMainBinding.textView.text = "텍스트뷰 - 메뉴2"
		R.id.context3 -> activityMainBinding.textView.text = "텍스트뷰 - 메뉴3"
        }
	return super.onContextItemSelected(item)
}
  • listView에 context menu 설정
    • menu를 확인하기 위해 길게 누른 뷰가 무엇인지 구분할 방법 X
      • item.menuInfo : listView 항목 중 선택된 항목 정보 가져오기
override fun onContextItemSelected(item: MenuItem): Boolean {
	when (item.itemId) {
		R.id.list_menu1 -> {
			val info  = item.menuInfo as AdapterView.AdapterContextMenuInfo
            activityMainBinding.textView.text = "리스트뷰 - ${dataList[info.position]}의 메뉴1"
		}
        R.id.list_menu2 -> {
			val info  = item.menuInfo as AdapterView.AdapterContextMenuInfo
			activityMainBinding.textView.text = "리스트뷰 - ${dataList[info.position]}의 메뉴2"
        }
        R.id.list_menu3 -> {
        	val info  = item.menuInfo as AdapterView.AdapterContextMenuInfo
             activityMainBinding.textView.text = "리스트뷰 - ${dataList[info.position]}의 메뉴3"
		}
	}
	return super.onContextItemSelected(item)
}


recyclerView에 context menu 설정

  • setOnCreateContextMenuListener : 항목 하나의 View에 context menu 생성 이벤트
    • rowBinding.root : 현재 번째의 항목 전체
  • setOnMenuItemClickListener : context menu의 항목을 선택했을 때 호출되는 리스너
inner class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolderClass>() {
	inner class ViewHolderClass(rowBinding: RowBinding) : ViewHolder(rowBinding.root) {
   
		init {
        	// context 메뉴 구성 (context 메뉴 활성화)
			rowBinding.root.setOnCreateContextMenuListener { menu, v, menuInfo ->

				menu.setHeaderTitle("${studentList[adapterPosition].name}")
                menuInflater.inflate(R.menu.context_menu, menu)

				// context menu의 항목 선택시 실행되는 함수
				menu[0].setOnMenuItemClickListener {

					studentList.removeAt(adapterPosition)

 					// recyclerView 갱신
                    this@RecyclerViewAdapter.notifyDataSetChanged()
                    
                    false
				}
			}
		}
	}
}

0개의 댓글