Kotlin

[android : kotlin] 코틀린 컨텍스트 메뉴(Context Menu) 사용 예제

컨텍스트 메뉴 (Context Menu)는 롱클릭을 하면 나타나는 메뉴로, 리스트 뷰의 항목을 롱클릭했을 때 주로 사용한다. registerForContext()메소드를 사용하여 컨텍스트 메뉴를 등록한다. 사용자가 메뉴를 선택했을 때 호출되는 메서드는 onContextItemSelected()이다. 2개의 메서드를 사용하여 메서드를 등록하고 사용해보자.

컨텍스트 메뉴(Context Menu) 는 고정 된 모달 팝업 창에 항목을 표시한다. 공간이없는 경우 뷰 아래에 팝업 메뉴가 나타나거나 뷰 위에 팝업 메뉴가 나타나며 팝업메뉴 외부를 터치하면 자동으로 닫힌다.

 

■텍스트 뷰를 롱클릭 했을 때 나타나는 Context Menu 메뉴를 추가해보자.

menu 레이아웃을 먼저 추가한다. 

왼쪽 Project탭에서 res폴더를 클릭 후 마우스 오른쪽 버튼을 눌러 NEW > Android Resource File 를 클릭한다. 리소스 타입으로 Menu를 선택 후 OK버튼을 클릭한다.


팔레트에서 Menu Item을 드래그하여 Componet Tree의 menu에 끌어다 놓습니다. 3개를 추가한다.


메뉴의 id값을 지정한다.


[popup_menu.xml] res/menu/폴더가 생성 되고 그 안에 popup_menu.xml 파일이 생성된다

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

    <item
        android:id="@+id/item1"
        android:title="Item1" />
    <item
        android:id="@+id/item2"
        android:title="Item2" />
    <item
        android:id="@+id/item3"
        android:title="Item3" />
</menu>

[MainActivity.kt] onCreateContextMenu()메서드와 onContextItemSelected()메서드를 오버라이드하여 코딩해주어야 한다.

package edu.kotlin.study

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.ContextMenu
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
import kotlinx.android.synthetic.main.activity_main.*

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

        registerForContextMenu(textView1)

    }

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)

        when (v?.id) {
            R.id.textView1 -> {
                menu?.setHeaderTitle("TextView의 메뉴")
                menuInflater.inflate(R.menu.popup_menu, menu)
            }
        }
    }

    override fun onContextItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            R.id.item1 -> textView1.text = "menu1"
            R.id.item2 -> textView1.text = "menu2"
            R.id.item3 -> textView1.text = "menu3"
        }
        return super.onContextItemSelected(item)
    }


}

[activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="텍스트뷰"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

</LinearLayout>

 

■리스트 뷰에 Context Menu를 추가하는 방법에 대해 알아보자.

[MainActivity.kt] onCreateContextMenu()메서드와 onContextItemSelected()메서드를 오버라이드하여 코딩해주어야 한다.

package edu.kotlin.study

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.ContextMenu
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    var dataArr = arrayOf("사과", "복숭아", "오렌지", "자두", "배")

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

        var simpleListAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, dataArr)

        listView1.adapter = simpleListAdapter


        //리스너 구현 방법 2 : 람다식 사용 : 오버라이드해야할 메서드가 1개 임으로 가능하다.
        listView1.setOnItemClickListener { _, _, position, _ ->
            textView1.text = dataArr[position]
        }

        registerForContextMenu(listView1)

    }

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)

        when (v?.id) {

            R.id.listView1 -> {
                menu?.setHeaderTitle("listView의 메뉴")
                menuInflater.inflate(R.menu.popup_menu, menu)

                //코드 작성으로 메뉴를 추가하는 방법이다.
                var menuInfo = menuInfo as AdapterView.AdapterContextMenuInfo
                if (menuInfo.position % 2 == 0) {
                    menu?.add(Menu.NONE, Menu.FIRST + 100, Menu.NONE, "menu4")
                }
            }
        }
    }

    override fun onContextItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            R.id.item1 -> {
                textView1.text = "menu1n"
                var menuInfo = item?.menuInfo as AdapterView.AdapterContextMenuInfo
                textView1.append("${menuInfo.position}  번째 메뉴 클릭됨")
            }
            R.id.item2 -> textView1.text = "menu2"
            R.id.item3 -> textView1.text = "menu3"
        }
        return super.onContextItemSelected(item)
    }

}

레이아웃이 아닌 코드를 통하여 메뉴를 추가를 할 경우 , menuInfo를 AdapterContextMenuInfo로 형변환 후 메뉴를 추가할 수 있다. 또 한 몇 번째 메뉴를 클릭했는지 position 값도 알 수 있다.

 

[activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="텍스트뷰"
        android:textAppearance="@style/TextAppearance.AppCompat.Display2" />

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


</LinearLayout>


[build.gradle(:app)]

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "edu.kotlin.study"
        minSdkVersion 22
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.1'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}

 

Leave a Reply

error: Content is protected !!