IDE/AndroidStudio

μ•ˆλ“œλ‘œμ΄λ“œ 이벀트 (Android Event)

μ„œλ¦¬β˜… 2024. 7. 12. 14:20

πŸš€ 개발 ν™˜κ²½
β–ͺ  IDE : Android Studio Koala 2024.1.1
β–ͺ  JAVA : 17.0.10 

 


 

1. 이벀트 λ¦¬μŠ€λ„ˆ (Event Listener)

 μ΄λ²€νŠΈ λ¦¬μŠ€λ„ˆλŠ” μ‚¬μš©μž μž…λ ₯(클릭, ν„°μΉ˜ λ“±)μ΄λ‚˜ μ‹œμŠ€ν…œ 이벀트λ₯Ό μ²˜λ¦¬ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€. νŠΉμ • μ΄λ²€νŠΈκ°€ λ°œμƒν–ˆμ„ λ•Œ μ–΄λ–€ λ™μž‘μ„ μˆ˜ν–‰ν• μ§€ μ •μ˜ν•˜λŠ” 역할을 ν•œλ‹€. 이벀트 λ¦¬μŠ€λ„ˆλŠ” μ—¬λŸ¬ λ·°(View)μ—μ„œ 곡유될 수 μžˆλ‹€.

 

 


 

2. 자주 μ‚¬μš©ν•˜λŠ” 4κ°€μ§€ 이벀트 λ¦¬μŠ€λ„ˆ

1) onClick() : μ‚¬μš©μžκ°€ μ–΄λ–€ ν•­λͺ©μ„ ν„°μΉ˜ν–ˆμ„ λ•Œ

2) onLongClick() : ν„°μΉ˜ν•˜κ³  일정 μ‹œκ°„ λ™μ•ˆ λˆ„λ₯΄κ³  μžˆμ„ λ•Œ

3) onFocusChange() : ν¬μ»€μŠ€κ°€ 이동될 λ•Œ

4) onKey() : 포컀슀 μœ„μ—μ„œ ν‚€λ₯Ό λˆ„λ₯΄κ³  놓을 λ•Œ

 

 


3. 이벀트 처리 κ³Όμ •

이벀트 λ°œμƒ -> λ¦¬μŠ€λ„ˆ 호좜  -> 둜직 μ‹€ν–‰

 

 


 

4. 이벀트 λ¦¬μŠ€λ„ˆ 등둝 방법

 

1) XMLμ—μ„œ 이벀트 λ¦¬μŠ€λ„ˆ 등둝

 XML λ ˆμ΄μ•„μ›ƒ νŒŒμΌμ—μ„œ 뷰에 직접 이벀트 λ¦¬μŠ€λ„ˆλ₯Ό 등둝할 수 μžˆλ‹€.

μž₯점: κ°„λ‹¨ν•˜κ³  직관적이닀. λ ˆμ΄μ•„μ›ƒκ³Ό 둜직이 λΆ„λ¦¬λ˜μ–΄ 가독성이 μ’‹λ‹€.

단점: λ¦¬νŒ©ν† λ§μ΄ μ–΄λ ΅λ‹€. λ©”μ„œλ“œ 이름이 λ³€κ²½λ˜κ±°λ‚˜ λ²„νŠΌ IDκ°€ 변경될 경우 XMLκ³Ό μ½”λ“œλ₯Ό λͺ¨λ‘ μˆ˜μ •ν•΄μ•Ό ν•œλ‹€. λŒ€κ·œλͺ¨ ν”„λ‘œμ νŠΈμ—μ„œ λ§Žμ€ λ²„νŠΌκ³Ό λ©”μ„œλ“œλ₯Ό 관리할 λ•Œ, XMLκ³Ό Java/Kotlin μ½”λ“œ κ°„μ˜ 연결이 λ³΅μž‘ν•΄μ§€κ³ , μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ ΅λ‹€.

 

πŸ“‘ activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="myEvent"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

πŸ“‘ MainActivity.kt

package com.example.event_test

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

// XMLμ—μ„œ 뷰에 미리 이벀트λ₯Ό 등둝할 것
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    // myEvent λ©”μ„œλ“œλŠ” XML λ ˆμ΄μ•„μ›ƒ νŒŒμΌμ—μ„œ λ²„νŠΌμ˜ onClick 속성에 μ—°κ²°λœ λ©”μ„œλ“œ
    fun myEvent(view: View) {
        // λ²„νŠΌ 클릭 μ‹œ μ²˜λ¦¬ν•  둜직
        Toast.makeText(applicationContext, "λ²„νŠΌ 클릭됨", Toast.LENGTH_SHORT).show()
    }
}

 

 

2) ν΄λž˜μŠ€μ—μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ 이벀트 λ¦¬μŠ€λ„ˆ 등둝

 MainActivity ν΄λž˜μŠ€μ— View.OnClickListener μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ λ¦¬μŠ€λ„ˆλ₯Ό μ—°κ²°ν•  수 μžˆλ‹€.

* onClick λ©”μ„œλ“œ λ‚΄μ—μ„œ λͺ¨λ“  뷰의 이벀트λ₯Ό κ΄€λ¦¬ν•˜λ―€λ‘œ μ’‹μ§€ μ•Šλ‹€κ³  μƒκ°ν•œλ‹€.

μž₯점: 이벀트 처리λ₯Ό ν•˜λ‚˜μ˜ λ©”μ„œλ“œμ—μ„œ 관리할 수 μžˆμ–΄ 이벀트λ₯Ό ν•œ κ³³μ—μ„œ μ²˜λ¦¬ν•˜κΈ° μš©μ΄ν•˜λ‹€.

단점: μ—¬λŸ¬ 뷰의 이벀트λ₯Ό ν•œ κ³³μ—μ„œ μ²˜λ¦¬ν•˜λ©΄ λ©”μ„œλ“œκ°€ κΈΈμ–΄μ§€κ³  가독성이 λ–¨μ–΄μ§ˆ 수 μžˆλ‹€. 

 

πŸ“‘ activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="275dp"
        android:text="Button1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button1" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

πŸ“‘ MainActivity.kt

package com.example.ex_event

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

// MainActivity ν΄λž˜μŠ€λŠ” View.OnClickListenerλ₯Ό κ΅¬ν˜„
class MainActivity : AppCompatActivity(), View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // XML λ ˆμ΄μ•„μ›ƒ νŒŒμΌμ—μ„œ λ²„νŠΌμ„ μ°Ύμ•„ λ³€μˆ˜μ— ν• λ‹Ή
        val button1: Button = findViewById(R.id.button1)
        val button2: Button = findViewById(R.id.button2)
        
        // λ²„νŠΌμ— 클릭 λ¦¬μŠ€λ„ˆ 등둝
        button1.setOnClickListener(this)
        button2.setOnClickListener(this)
    }

    // onClick λ©”μ„œλ“œλŠ” λ²„νŠΌ 클릭 μ‹œ 호좜됨
    override fun onClick(view: View) {
        // 클릭된 뷰의 id에 따라 λ‹€λ₯΄κ²Œ 처리
        when (view.id) {
            // λ²„νŠΌ 클릭 μ‹œ μ²˜λ¦¬ν•  둜직
            R.id.button1 -> Toast.makeText(applicationContext, "λ²„νŠΌ 1 클릭됨", Toast.LENGTH_SHORT).show()
            R.id.button2 -> Toast.makeText(applicationContext, "λ²„νŠΌ 2 클릭됨", Toast.LENGTH_SHORT).show()
        }
    }
}

 

 

3) 읡λͺ… ν΄λž˜μŠ€μ™€ λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜μ—¬ 이벀트 λ¦¬μŠ€λ„ˆ 등둝

 μ΅λͺ…ν΄λž˜μŠ€μ™€ λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜μ—¬ 이벀트λ₯Ό 등둝할 수 μžˆλ‹€. 단, λžŒλ‹€ ν‘œν˜„μ‹μ€ Java 8 μ΄μƒμ—μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

μž₯점: μ½”λ“œκ°€ 맀우 κ°„κ²°ν•˜λ‹€. ν•„μš”ν•  λ•Œλ§ˆλ‹€ λ¦¬μŠ€λ„ˆλ₯Ό μ •μ˜ν•  수 μžˆμ–΄ μ½”λ“œκ°€ λΆ„λ¦¬λ˜κ³  κ΄€λ¦¬ν•˜κΈ° 쉽닀.

단점: 읡λͺ… 클래슀λ₯Ό κ³Όλ„ν•˜κ²Œ μ‚¬μš©ν•  경우 μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§ˆ 수 μžˆλ‹€. λžŒλ‹€ ν‘œν˜„μ‹μ€ Java 8 μ΄μƒμ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.

 

πŸ“‘ activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="275dp"
        android:text="Button1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button1" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

πŸ“‘ MainActivity.kt

package com.example.ex_event

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

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

        // XML λ ˆμ΄μ•„μ›ƒ νŒŒμΌμ—μ„œ λ²„νŠΌμ„ μ°Ύμ•„ λ³€μˆ˜μ— ν• λ‹Ή
        val button1: Button = findViewById(R.id.button1)
        val button2: Button = findViewById(R.id.button2)

        // 읡λͺ… 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ 클릭 λ¦¬μŠ€λ„ˆ μ„€μ •
        button1.setOnClickListener(object : View.OnClickListener {
            override fun onClick(view: View?) {
                // λ²„νŠΌ 클릭 μ‹œ μ²˜λ¦¬ν•  둜직
                Toast.makeText(applicationContext, "λ²„νŠΌ 1 클릭됨", Toast.LENGTH_SHORT).show()
            }
        })

        // λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜μ—¬ 클릭 λ¦¬μŠ€λ„ˆ μ„€μ •
        button2.setOnClickListener {
            // λ²„νŠΌ 클릭 μ‹œ μ²˜λ¦¬ν•  둜직
            Toast.makeText(applicationContext, "λ²„νŠΌ 2 클릭됨", Toast.LENGTH_SHORT).show()
        }
    }
}

 

* 읡λͺ… ν΄λž˜μŠ€μ—μ„œλŠ” View 객체가 null일 κ°€λŠ₯성을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ view: View?λ₯Ό μ‚¬μš©ν•œλ‹€. λžŒλ‹€ ν‘œν˜„μ‹μ—μ„œλŠ” View 객체가 null이 될 κ°€λŠ₯성이 μ—†λ‹€κ³  κ°€μ •ν•˜κΈ° λ•Œλ¬Έμ— view: Viewλ₯Ό μ‚¬μš©ν•œλ‹€. μ΄λŸ¬ν•œ 차이점은 λžŒλ‹€ ν‘œν˜„μ‹μ˜ 간결함과View.OnClickListener μΈν„°νŽ˜μ΄μŠ€μ˜ λ™μž‘ λ°©μ‹μ—μ„œ λΉ„λ‘―λœλ‹€.

 

 XMLμ—μ„œ 이벀트 λ¦¬μŠ€λ„ˆλ₯Ό λ“±λ‘ν•˜λŠ” 방법은 κ°„λ‹¨ν•˜κ³  μ§κ΄€μ μ΄μ§€λ§Œ μœ μ—°μ„±μ΄ λ–¨μ–΄μ§€λ©°, MainActivity ν΄λž˜μŠ€μ— μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 방법은 ν•œ κ³³μ—μ„œ 관리가 κ°€λŠ₯ν•˜μ§€λ§Œ 가독성이 λ–¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. 읡λͺ… ν΄λž˜μŠ€μ™€ λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•˜λŠ” 방법은 μ½”λ“œκ°€ κ°„κ²°ν•΄μ§€κ³  μœ μ—°μ„±μ΄ λ†’λ‹€. 이런 점을 λ³Ό λ•Œ, κ°€μž₯ μ‚¬μš©ν•˜κΈ° νŽΈν•œ 것은 λžŒλ‹€ ν‘œν˜„μ‹μ΄λΌκ³  μƒκ°ν•œλ‹€.