안드로이드

[Android Kotlin] 안드로이드 코틀린 Context Menu

행복하개! 2020. 3. 26. 22:19

Context Menu는 Option Menu와 다르게 어떠한 위젯이나 뷰에 메뉴를 붙일 때 사용한다. 예시로 보여줄 TextView와 ListView에 연결해서 꾹 누르면 해당하는 위젯 위에 옵션이 쭈룩 나온다. 

 

먼저 Option Menu와 동일하게 menu를 만들자. (res -> new -> Android Resource File -> values를 menu로) 

 

textview_menu.xml

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

    <item
        android:id="@+id/tv_Item1"
        android:title="tv_Item1" />
    <item
        android:id="@+id/tv_Item2"
        android:title="tv_Item2" />
</menu>

 

listview_menu.xml

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

    <item
        android:id="@+id/lv_item1"
        android:title="Item" />
    <item
        android:id="@+id/lv_item2"
        android:title="Item" />
</menu>

 

MainActivity.kt

class MainActivity : AppCompatActivity() {

    var data = arrayOf("리스트1", "리스트2", "리스트3", "리스트4", "리스트5")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
        lv1.adapter = adapter

        lv1.setOnItemClickListener { adapterView, view, i, l ->
            tv1.text = "${i} 터치"
        }

        // 등록
        registerForContextMenu(tv1)
        registerForContextMenu(lv1)
    }

    override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) { // v 사용자가 길게 누른 것
        super.onCreateContextMenu(menu, v, menuInfo)

        when (v?.id) {
            // 1. textview에 연결
            R.id.tv1 -> {
                menu?.setHeaderTitle("tv의 메뉴")
                menuInflater.inflate(R.menu.textview_menu, menu)
            }
            // 2. listview에 연결
            R.id.lv1 -> {
                menu?.setHeaderTitle("lv의 메뉴")
                menuInflater.inflate(R.menu.listview_menu, menu)

                var info = menuInfo as AdapterView.AdapterContextMenuInfo
                if (info.position % 2 == 0) {
                    menu?.add(Menu.NONE, Menu.FIRST + 100, Menu.NONE, "리스트뷰 메뉴3")
                }
            }
        }
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when (item?.itemId) {
            R.id.tv_Item1 ->
                tv1.text = "1"
            R.id.tv_Item2 ->
                tv1.text = "2"
            R.id.lv_item1 -> {
                tv1.text = "lv1"
                var info = item.menuInfo as AdapterView.AdapterContextMenuInfo
                tv1.append("${info.position} 번째 항목")
            }
            R.id.lv_item2 -> {
                tv1.text = "lv2"
                var info = item.menuInfo as AdapterView.AdapterContextMenuInfo
                tv1.append("${info.position} 번째 항목")
            }
        }

        return super.onContextItemSelected(item)
    }
}

Option Menu와 거의 동일하게 메서드가 존재한다. onCreateContextMenu의 v로 들어오는 것은 꾹 눌린 뷰가 무엇인지 정보가 들어온다. 해당하는 뷰일 경우 menu를 inflate하여 띄우게 된다. 하지만 ListView의 경우에는 눌린 뷰의 몇번째인지 position을 알아야 하는데, 그것은 menuInfo을 통해서 구할 수 있다. AdapterView.AdapterContextMenuInfo로 형변환하여 포지션 값을 뽑아 낼 수 있다. 이것은 onContextItemSelected에서도 마찬가지다. item에 menuInfo가 숨어져서 온다. 위의 코드 처럼 캐스팅하여 사용하면 된다. 상황에 맞게 사용하면 될 것 같다. 

 

 

 

1. TextView를 길게 눌렀을 때
2. ListView를 길게 눌렀을 때

 

 

 

여담이지만 안이뻐보이는건 얼마든지 이쁘게 커스텀 하면 된다. 안이쁘다고 실망하지 말자!

 

 

 

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/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        style="@style/TextAppearance.AppCompat.Large"/>

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

</LinearLayout>