Archives
Recent Posts
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[34일차 Android] Context Menu 본문

Computer/Android

[34일차 Android] Context Menu

Wise-99 2023. 6. 17. 17:48

 

 

 

출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT

 

 

 

📖 Context Menu

  • 화면에 배치된 View에 설정할 수 있는 메뉴
  • 메뉴가 설정된 View를 길게 누르면 메뉴가 나타난다.

registerForContext

  • Context Menu를 등록하는 메서드
  • 메서드의 매개 변수로 넣어준 View 객체에 메뉴가 설정된다.

onCreateContextMenu

  • View를 길게 누르면 호출되는 메서드
  • 여기에서 메뉴를 구성한다.

 

 

 

예제 코드

context_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/context1"
        android:title="컨텍스트 메뉴1" />
    <item
        android:id="@+id/context2"
        android:title="컨텍스트 메뉴2" />
    <item
        android:id="@+id/context3"
        android:title="컨텍스트 메뉴3" />
</menu>

 

 

 

list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/list_menu1"
        android:title="리스트 메뉴1" />
    <item
        android:id="@+id/list_menu2"
        android:title="리스트 메뉴2" />
    <item
        android:id="@+id/list_menu3"
        android:title="리스트 메뉴3" />
</menu>

 

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 

 

 

MainActivity.kt

class MainActivity : AppCompatActivity() {

    lateinit var activityMainBinding: ActivityMainBinding

    val dataList = arrayOf(
        "항목1", "항목2", "항목3", "항목4", "항목5"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(activityMainBinding.root)

        activityMainBinding.run {

            registerForContextMenu(textView)

            registerForContextMenu(listView)

            listView.run {
                adapter = ArrayAdapter<String>(
                    this@MainActivity, android.R.layout.simple_list_item_1, dataList
                )
            }
        }
    }

    // 두번째 매개 변수(v) : 사용자가 길게 누르면 뷰 객체가 들어온다.
    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)

        // View의 아이디로 분기한다.
        if (v != null){
            when(v?.id){
                // textView
                R.id.textView -> {
                    menu?.setHeaderTitle("텍스트 뷰의 메뉴")
                    menuInflater.inflate(R.menu.context_menu, menu)
                }

                R.id.listView -> {
                    val info = menuInfo as AdapterView.AdapterContextMenuInfo
                    menu?.setHeaderTitle("${dataList[info.position]}의 메뉴")
                    menuInflater.inflate(R.menu.list_menu, menu)
                }
            }
        }
    }

    // 컨텍스트 메뉴의 항목을 터치했을 때 호출되는 메서드
    override fun onContextItemSelected(item: MenuItem): Boolean {

        when(item.itemId){
            // TextView의 컨텍스트 메뉴
            R.id.context1 -> activityMainBinding.textView.text = "텍스트 뷰 - 메뉴1"
            R.id.context2 -> activityMainBinding.textView.text = "텍스트 뷰 - 메뉴2"
            R.id.context3 -> activityMainBinding.textView.text = "텍스트 뷰 - 메뉴3"

            //ListView의 컨텍스트 메뉴
            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)
    }
}

 

 

 

코드 리뷰

        activityMainBinding.run {

            registerForContextMenu(textView)

            registerForContextMenu(listView)

            listView.run {
                adapter = ArrayAdapter<String>(
                    this@MainActivity, android.R.layout.simple_list_item_1, dataList
                )
            }
        }
  • registerForContextMenu(textView) : textView에 컨텍스트 메뉴를 등록한다.
  • registerForContextMenu(listView) : ListView에 컨텍스트 메뉴를 등록한다.
  • listView.run { ... } : listView의 layout과 데이터를 설정한다.

 

override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) { ... }
  • menu?.setHeaderTitle() : 메뉴의 제목을 설정한다.

 

  • val info = menuInfo as AdapterView.AdapterContextMenuInfo
    • 세번째 매개 변수로 들어오는 객체로부터 사용자가 길게 누른 항목이 몇번째인지 파악한다.

 

override fun onContextItemSelected(item: MenuItem): Boolean { ... }
  • 이 메서드에서 메뉴를 띄우기 위해 길게 누른 뷰가 무엇인지 구분할 방법이 없다.
  • 이에 서로 다른 뷰의 컨텍스트 메뉴라고 하더라도 메뉴의 id는 다 다르게 구성해줘야 한다.
  • 터치한 item을 받아 id로 분기하여 처리한다.

 

 

 

결과

'Computer > Android' 카테고리의 다른 글

[34일차 Android] Activity  (0) 2023.06.17
[34일차 Android] Popup Menu  (0) 2023.06.17
[34일차 Android] Option Menu  (0) 2023.06.17
[33일차 Android] Permission  (0) 2023.06.17
[32일차 Android] RecyclerView  (0) 2023.06.16