터치 이벤트
- 터치 이벤트의 콜백 함수인 onTouchEvent()를 선언
- 매개변수는 MotionEvent 객체
- 이 객체에 터치의 종류와 발생 지점(좌푯값)이 담김
class MainActivity1 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main1)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
return super.onTouchEvent(event)
}
}
터치 이벤트의 종류
- ACTION_DOWN: 화면을 손가락으로 누른 순간의 이벤트
- ACTION_UP: 화면에서 손가락을 떼는 순간의 이벤트
- ACTION_MOVE: 화면을 손가락으로 누른 채로 이동하는 순간의 이벤트
override fun onToucEvent(event: MotionEvent?): Boolean {
when(event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("hahee", "Touch down event")
}
MotionEvent.ACTION_UP -> {
Log.d("hahee", "Touch up event")
}
}
return super.onTouchEvent(event)
}
터치 이벤트 발생 좌표 얻기
- onTouchEvent() 함수의 매개변수인 MotionEvent 객체로 획득
- x: 이벤트가 발생한 뷰의 X 좌표
- y: 이벤트가 발생한 뷰의 Y 좌표
- rawX: 화면의 X 좌표 (모니터 시작지점 ~)
- rawY: 화면의 Y 좌표 (모니터 시작지점 ~)
override fun onToucEvent(event: MotionEvent?): Boolean {
when(event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("hahee", "Touch down event x: ${event.x}, rawX: ${event.rawX}")
}
}
return super.onTouchEvent(event)
}
키 이벤트
- 사용자가 폰의 키를 누르는 순간에 발생
- 콜백 함수
- onKeyDown: 키를 누른 순간의 이벤트
- onKeyUp: 키를 떼는 순간의 이벤트
- onKeyLongPress: 키를 오래 누르는 순간의 이벤트
class MainActivity2 : AppCompatActivity() {
...
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
Log.d("hahee", "onKeyDown")
return super.onKeyDown(keyCode, event)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
Log.d("hahee", "onKeyUp")
return super.onKeyUp(keyCode, event)
}
}
- 첫 번째 매개변수는 키의 코드이며 이 값으로 사용자가 어떤 키를 눌렀는지 식별
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode) {
KeyEvent.KEYCODE_0 -> Log.d("hahee", "0 키를 눌렀네요")
KeyEvent.KEYCODE_A -> Log.d("hahee", "A 키를 눌렀네요")
}
return super.onKeyDown(keyCode, event)
}
- 키 이벤트가 발생하는 키는 폰에서 제공하는 소프트 키보드의 키를 의미하지 않음
- 안드로이드 시스템 버튼도 키로 취급하므로 이 버튼의 이벤트를 처리
- 뒤로가기 버튼 이벤트에는 앞에서 살펴본 onKeyDown()이나 onKeyUp() 함수를 이용할 수도 있지만 onBackPressed() 함수를 이용할 수도 있음
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode) {
KeyEvent.KEYCODE_BACK -> Log.d("hahee", "BACK 키를 눌렀네요")
KeyEvent.KEYCODE_VOLUME_UP -> Log.d("hahee", "VOLUME_UP 키를 눌렀네요")
KeyEvent.KEYCODE_VOLUME_DOWN -> Log.d("hahee", "VOLUME_DOWN 키를 눌렀네요")
}
return super.onKeyDown(keyCode, event)
}
뒤로가기와 볼륨 조절 버튼 이벤트 처리
override fun onBackPressed() {
Log.d("hahee", "BACK 키를 눌렀네요")
}
뒤로가기 버튼의 이벤트 처리
뷰 이벤트의 처리 구조
- 뷰 이벤트 처리는 이벤트 소스와 이벤트 핸들러로 역할이 나뉘며 이 둘을 리스너로 연결해야 이벤트를 처리 가능
- 이벤트 소스: 이벤트가 발생한 객체
- 이벤트 핸들러: 이벤트 발생 시 실행할 로직이 구현된 객체
- 리스너: 이벤트 소스와 이벤트 핸들러를 연결해 주는 함수
binding.checkbox.setOnCheckedChangeListener(object: CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
Log.d("hahee", "체크박스 클릭")
}
})
체크 박스 이벤트 처리
- 이벤트 소스 : checkbox
- 리스너(이벤트 핸들러 등록) : setOnCheckedChangeListener
- object: 이벤트 핸들러
class MainActivity3 : AppCompatActivity(), CompoundButton.OnCheckedChangeListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMain3Binding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener(this)
}
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
Log.d("hahee", "체크박스 클릭")
}
}
activity에서 interface 구현 예제
class MyEventHandler : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
Log.d("hahee", "체크박스 클릭")
}
}
class MainActivity3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMain3Binding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener(MyEventHandler())
}
}
이벤트 핸들러를 별도의 클래스로 만든 예제
class MainActivity3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMain3Binding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener {
compoundButton, b ->
Log.d("hahee", "체크박스 클릭")
}
}
}
SAM 기법으로 구현 예제
꼭 해당 모듈(ch8_event)의 build.gradle파일의
android {
...
viewBinding {
enabled = true
}
}
android {...}안에 viewBinding { enabled=true }를 넣어주어야 한다.
클릭 이벤트 처리 예제 #1
package com.example.ch8_event
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.example.ch8_event.databinding.ActivityMain1Binding
class MainActivity1 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMain1Binding.inflate(layoutInflater)
setContentView(binding.root)
binding.btn.setOnClickListener {
binding.btn.visibility = View.INVISIBLE
binding.imgView.visibility = View.VISIBLE
}
binding.imgView.setOnClickListener {
binding.btn.visibility = View.VISIBLE
binding.imgView.visibility = View.INVISIBLE
}
}
}
MainActivity1
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/mallang" />
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button1" />
</FrameLayout>
activity_main1.xml
꼭 manifest파일에서 MainActivity1으로 바꿔주어야 한다.(해당 파일로)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ch8_event">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ProApplication">
<activity
android:name=".MainActivity1"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- 결과 -
TOUCH_DOWN, TOUCH_UP 처리 예제 #2
package com.example.ch8_event
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
class MainActivity3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
when(event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("hahee", "Touch down event")
}
MotionEvent.ACTION_UP -> {
Log.d("hahee", "Touch up event")
}
}
return super.onTouchEvent(event)
}
}
MainActivity3
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imgView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/mallang" />
</FrameLayout>
activity_main3.xml
manifest파일도 MainActivity3으로 바꿔주었다.
- 결과 -
밑의 Logcat에 Touch down event, Touch up event가 출력됨
TOUCH_DOWN 시 좌표값 얻기 예제 #3
package com.example.ch8_event
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
class MainActivity4 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
when(event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("hahee", "Touch down event x: ${event.x}, rawx : ${event.rawX}")
}
}
return super.onTouchEvent(event)
}
}
MainActivity4
manifest 를 MainActivity4로 수정해주었고,
xml파일은 위 2번째 예제 그대로 activity_main3.xml을 사용하였다.
- 결과 -
밑에 Logcat에 좌표값이 찍힌다.
x, rawX
onKeyDown, onKeyUp 예제 #4
package com.example.ch8_event
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import androidx.appcompat.app.AppCompatActivity
class MainActivity5 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
Log.d("hahee", "onKeyDown")
return super.onKeyDown(keyCode, event)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
Log.d("hahee", "onKeyUp")
return super.onKeyUp(keyCode, event)
}
}
MainActivity5
manifest 를 MainActivity5로 수정해주었고,
xml파일은 위 2번째 예제 그대로 activity_main3.xml을 사용하였다.
onKeyDown - 키를 누른 순간의 이벤트
onKeyUp: 키를 떼는 순간의 이벤트
- 결과 -
앱 실행 후,
키보드를 사용하여 키를 입력해보면 밑에 onKeyDown, onKeyUp으로 이벤트가 발생하는 것을 확인할 수 있다.
checkbox 이벤트 예제 #5
package com.example.ch8_event
import android.os.Bundle
import android.util.Log
import android.widget.CompoundButton
import androidx.appcompat.app.AppCompatActivity
import com.example.ch8_event.databinding.ActivityMain6Binding
class MainActivity6 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMain6Binding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox1.setOnCheckedChangeListener(object : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
Log.d("hahee", "체크박스를 클릭했습니다.")
}
})
}
}
MainActivity6
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="@+id/checkbox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
activity_main6.xml
manifest를 MainActivity6로 변경
- 결과 -
체크박스를 클릭함에 따라 Logcat에 해당 로그문이 출력된다.
'Android Studio' 카테고리의 다른 글
안드로이드 #9 : Resource 230306 (0) | 2023.03.06 |
---|---|
안드로이드 #8 : chronometer 스탑워치 앱 230306 (0) | 2023.03.06 |
안드로이드 #6 : 전화걸기 화면에서 숫자누르기, back버튼, #(리셋) 기능 추가(이벤트 실습) 230303 (0) | 2023.03.03 |
안드로이드 #5 : 전화걸기 화면 만들어보기(레이아웃 실습) 230303 (0) | 2023.03.03 |
안드로이드 #4 : 레이아웃 230302 (0) | 2023.03.03 |
댓글