개발 공부/안드로이드

android contextMenu - 선택지 띄우기, recyclerview

yong_DD 2022. 7. 3. 16:02

contextMenu란?

윈도우에서 해당 화면에 오른쪽 클릭을 했을 때 나오는 메뉴(선택지)처럼 안드로이드에서도 동일하게 해당 뷰를 길게 클릭하면 나오는 메뉴들을 말한다.

 

윈도우 화면

1. activity에서 contextMenu 사용하기

예시) 전화번호를 클릭하면 해당 전화번호를 전화를 걸지, 메시지를 보낼지, 복사할 지 선택하는 메뉴 띄우기

완료화면

 

1-1 해당 반응을 받을 뷰를 작성registerForContextMenu(해당 뷰)

1-2 onCreateContextMenu 에 띄울 메뉴 설정

   override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)
        menu?.add("전화")
        menu?.add("메시지")
        menu?.add("복사")
    }

1-3 onContextItemSelected에 메뉴를 클릭했을 경우 처리!

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when(item.title){
            "전화" -> {
                val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumberTextView.text.toString(), null))
                startActivity(intent)
            }
            "메시지" -> {
                val smsUri = Uri.parse("sms:"+phoneNumberTextView.text.toString())
                val sendIntent = Intent(Intent.ACTION_SENDTO, smsUri)
                startActivity(sendIntent)
            }
            "복사" -> {
                val clipBoard: ClipboardManager =
                    getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip = ClipData.newPlainText("location",phoneNumberTextView.text.toString())
                clipBoard.setPrimaryClip(clip)
            }
        }

        return super.onContextItemSelected(item)
    }

 

[전체코드]

class ContextMenuActivity : AppCompatActivity() {

    private val phoneNumberTextView: TextView by lazy{
        findViewById(R.id.phoneNumber)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_context_menu)

        registerForContextMenu(phoneNumberTextView)
    }

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)
        menu?.add("전화")
        menu?.add("메시지")
        menu?.add("복사")
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when(item.title){
            "전화" -> {
                val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumberTextView.text.toString(), null))
                startActivity(intent)
            }
            "메시지" -> {
                val smsUri = Uri.parse("sms:"+phoneNumberTextView.text.toString())
                val sendIntent = Intent(Intent.ACTION_SENDTO, smsUri)
                startActivity(sendIntent)
            }
            "복사" -> {
                val clipBoard: ClipboardManager =
                    getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip = ClipData.newPlainText("location",phoneNumberTextView.text.toString())
                clipBoard.setPrimaryClip(clip)
            }
        }

        return super.onContextItemSelected(item)
    }
}
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/phoneNumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="010-1234-5678"
        android:textColor="@color/black"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

추가 menu xml 사용하기

일일이 등록하지 않고 xml을 사용해서 만들 수도 있다.

* res → 'menu' directroy 생성 → menu xml 생성

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_call"
        android:title="전화"/>
    <item android:id="@+id/menu_message"
        android:title="메시지"/>
    <item android:id="@+id/menu_copy"
        android:title="복사"/>
</menu>

[수정된 코드]

    override fun onCreateContextMenu(
        menu: ContextMenu?,
        v: View?,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)
        val menuInflater = menuInflater
        menuInflater.inflate(R.menu.phone_action_menu,menu)
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            R.id.menu_call -> {
                val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumberTextView.text.toString(), null))
                startActivity(intent)
            }
            R.id.menu_message -> {
                val smsUri = Uri.parse("sms:"+phoneNumberTextView.text.toString())
                val sendIntent = Intent(Intent.ACTION_SENDTO, smsUri)
                startActivity(sendIntent)
            }
            R.id.menu_copy -> {
                val clipBoard: ClipboardManager =
                    getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip = ClipData.newPlainText("location",phoneNumberTextView.text.toString())
                clipBoard.setPrimaryClip(clip)
            }
        }

        return super.onContextItemSelected(item)
    }
​

 

2. recylerview에서 사용하기

2-1 recyclerview가 있는 activity 혹은 fragment 에registerForContextMenu(해당 recyclerview)

2-2 recyclerview adapter의 해당 ViewHolder에 View.OnCreateContextMenuListener 상속하기

2-3 init으로 해당 뷰를 리스너 등록!

2-4 해당 메뉴에 클릭 반응할 setOnMenuItemClickListener 달아주면 끝!

 

 inner class ViewHolder(val binding: ItemReservationBinding) : RecyclerView.ViewHolder(binding.root),View.OnCreateContextMenuListener {

        init {
            binding.cellPhoneNumber.setOnCreateContextMenuListener(this)
        }
...

 override fun onCreateContextMenu(
            menu: ContextMenu?,
            v: View?,
            menuInfo: ContextMenu.ContextMenuInfo?
        ) {
            val call = menu?.add(context.getString(R.string.call))
            val message = menu?.add(context.getString(R.string.message))
            val copy = menu?.add(context.getString(R.string.copy))

            call?.setOnMenuItemClickListener {
                val textView = v as TextView
                val number = textView.text.toString()
                val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", number, null))
                context.startActivity(intent)
                true
            }

            message?.setOnMenuItemClickListener {
                val textView = v as TextView
                val number = textView.text.toString()
                val smsUri = Uri.parse("sms:"+number);
                val sendIntent = Intent(Intent.ACTION_SENDTO, smsUri)
                context.startActivity(sendIntent)
                true
            }

            copy?.setOnMenuItemClickListener {
                val textView = v as TextView
                val number = textView.text.toString()
                val clipBoard: ClipboardManager =
                    context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip = ClipData.newPlainText("location",number)
                clipBoard.setPrimaryClip(clip)
                Toast.makeText(context,"복사되었습니다.",Toast.LENGTH_SHORT).show()
                true
            }
        }

 }