[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'
}