앱의 화면에서 발생하는 사용자 이벤트는 터치이다. 앱의 화면에서 발생하는 사용자의 터치 이벤트를 처리하고 싶다면 액티비티 클래스에 터치 이벤트의 콜백 함수인 onTouchEvent()를 선언하면 된다. 콜백 함수란 어떤 이벤트가 발생하거나 시점에 도달했을 때 시스템에서 자동으로 호출하는 함수이다.
함수에 전달되는 매개변수는 MotionEvent 객체이며, 이 객체에 터치의 종류와 발생 지점이 담긴다.
터치이벤트의 종류
override fun onTouchEvent(event: MotionEvent?): Boolean {
when(event?.action){
MotionEvent.ACTION_DOWN ->{
Log.d("joung","touch down")
}
MotionEvent.ACTION_UP ->{
Log.d("joung","touch UP")
}
}
return super.onTouchEvent(event)
}
터치 이벤트 발생 좌표 얻기
좌표역시 onTouchEvent() 함수의 매개변수인 MotionEvent 객체로 얻는다
override fun onTouchEvent(event: MotionEvent?): Boolean {
when(event?.action){
MotionEvent.ACTION_DOWN ->{
Log.d("joung","touch down" , ${event.x} , ${event.rawX})
}
}
return super.onTouchEvent(event)
}
키 이벤트는 사용자가 폰의 키를 누르는 순간 발생한다. 액티비티에서 키 이벤트를 처리하려면 다음과 같이 콜백 함수를 재정의해야 한다. 그럼 키 이벤트가 발생할 때 해당 함수가 자동으로 호출된다.
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
Log.d("joung","keyDown")
return super.onKeyDown(keyCode, event)
}
키 이벤트 함수의 첫 번째 매개변수는 키의 코드이며 이 값으로 사용자가 어떤 키를 눌렀는지 알 수 있다.
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode){
KeyEvent.KEYCODE_0 -> Log.d("Joung","0키를 눌렀네요")
}
return super.onKeyDown(keyCode, event)
}
뷰를 사용자가 터치했을 때 이벤트 처리는 앞에서 살펴본 터치 이벤트를 이용하지 않고 각 뷰에서 이벤트를 별도로 제공한다. 뷰 이벤트 처리는 이벤트 소스와 이벤트 핸들러로 역할이 나뉘며 이 둘을 리스너로 연결해야 이벤트를 처리할 수 있다.
이벤트 소스에 리스너로 이벤트 핸들러를 등록해 놓으면 이벤트가 발생할 때 실행되는 구조이다.
package com.example.androidlab
import android.os.Bundle
import android.util.Log
import android.widget.CompoundButton
import androidx.appcompat.app.AppCompatActivity
import com.example.androidlab.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener(object : CompoundButton.OnCheckedChangeListener{
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
Log.d("joung","체크박스 클릭")
}
})
}
}
안드로이드 앱 개발에서 리소스란 정적인 자원이라고 할 수 있다. 변경되지 않는 정적인 콘텐츠는 코드에 작성하지 않고 리소스로 분리해 외부 파일로 만들어 이용할 수 있다.
앱에서 이용하는 리소스는 크게 앱 리소스와 플랫폼 리소스로 구분된다.
앱 리소스란 개발자가 직접 추가한 리소스를 의미한다. 앱 개발을 위해 모듈을 만들면 res라는 디렉토리가 생기고 그 아래에 drawable, layout, mipmap, values라는 디렉토리가 4개가 생성된다. 개발자는 이 리소스 디렉터리에 리소스 파일을 각각 만든다.
모듈을 만들면 기본으로 디렉터리 4개가 만들어지지만 리소스 파일의 종류는 더 많다
디렉터리명 | 리소스 종류 |
---|---|
animator | 속성 애니메이션 XML |
anim | 트윈 애니메이션 XML |
color | 색상 상태 목록 정의 XML |
drawable | 이미지 리소스 |
mipmap | 앱 실행 아이콘 리소스 |
layout | 레이아웃 XML |
menu | 메뉴 구성 XML |
raw | 원시 형태로 이용되는 리소스 파일 |
values | 단순 값으로 이용되는 리소스 |
xml | 특정 디렉터리가 정의되지 않은 나머지 XML 파일 |
font | 글꼴 리소스 |
리소스 디렉터리와 파일을 이름을 지을 땐 위에 소개한 리소스 디렉터리명은 고정이며 res디렉터리 아래에 개발자가 임의로 이름을 붙인 디렉터리를 만들 수 없고 하위 디렉터리 역시 추가할 수 없다. 또한 리소스 파일명은 values에 추가하는 파일을 제외하고는 모두 자바의 이름 작성 규칙을 지켜야 하며 알파벳 대문자를 사용할 수 없다.
XML 이미지를 만들 때는 아래와 같은 태그로 표현한다.
shape | rectangle, oval, line, ring 중에서 선택할 수 있음 |
---|---|
corners | 둥근 모서리 그리는데 사용 |
gradient | 그라데이션 색상 지정 |
size | 도형의 크기 지정 |
solid | 도형의 색상 지정 |
stroke | 도형의 윤곽선 지정 |
개발자가 리소스를 따로 준비하지 않아도 이미 안드로이드 플랫폼이 제공하는 많은 리소스가 있다. 앱을 개발할 때 이러한 플랫폼 리소스를 활용할 수 있다. 플랫폼 리소스는 앱에 있는 리소스가 아니므로 앱의 R파일이 아니라 android.R 이라는 플랫폼 라이브러리의 R파일에 등록되어 있다. 따라서 android.R 파일을 이용해 플랫폼 리소스를 이용할 수 있다.
리소스 조건 설정이란 어떤 리소스를 특정 환경에서만 적용되도록 설정하는 것을 말한다. 조건 설정을 하는 이유는 쉬운 예시로 dpi가 다른 핸드폰에서 앱을 다운받아 실행 아이콘을 볼 때 하나의 실행아이콘 이미지만 있을 경우 이미지가 깨져보일 수 있어 다양한 크기의 이미지를 준비해 기기별로 맞는 이미지를 출력해 줘야한다.
리소스 조건을 이용하려면 아이콘의 파일명을 똑같이 지정해야 한다. 그러면 R 파일에는 식별자가 하나만 생성된다. 그러므로 코드에서 각 리소스를 구분할 필요 없이 R.mipmap에 지정된다. 이때 파일명이 중복되는 문제가 발생하는데 디렉터리를 구분해 해결한다. 이때 리소스 디렉터리 이름에서 붙임표(-) 뒤의 단어가 리소스의 조건이다. 즉, 이 디렉터리의 리소스가 어느 때에 적용되어야 하는지 명시하는 조건이다.