액티비티 화면은 TextView, EditText, ImageView, Button 등의 뷰로 화면을 구성하고 구현
이런 뷰들을 사용자가 터치했을 때 이벤트 처리
뷰 이벤트는 앞에서의 이벤트 콜백 함수로만 선언해서는 처리할 수 없음
뷰 이벤트 처리는 event source와 event handler로 나뉘며
둘을 listener로 연결해야 이벤트를 처리할 수 있음
이벤트가 발생한 객체
이벤트 발생 시 실행할 로직이 구현된 객체
이벤트 소스와 이벤트 핸들러를 연결해 주는 함수
이벤트 소스에 리스너로 이벤트 핸들러를 등록해 놓으면 이벤트가 발생할 때 실행되는 구조
/* 이벤트 소스 | 리스너(이벤트 핸들러 등록) | 이벤트 핸들러 */
binding.checkbox.setOnCheckedChangeListener(object: CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1:Boolean) {
Log.d("test", "Checkbox click")
}
})
/*
checkbox - 이벤트 소스
setOnCheckedChangeListener - 리스너(이벤트 핸들러 등록)
object - 이벤트 핸들러
*/
- 액티비티 자체에서 인터페이스를 구현 할 수 있음
class MainActivity3 : AppCompatActivity(), CompoundButton.OnCheckedChangeListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(svaedInstanceState) val binding = ActivityMain3Binding.inflate(layoutInflater) setContentView(binding.root) binding.checkbox.setOnCheckedChangeListener(this) } override fun onCheckedChanged(p0: CompoundButton?, p1:Boolean) { Log.d("test", "Checkbox click") } }
- 이벤트 핸들러를 별도의 클래스로 만들어 처리 가능
class MyEventHandler : CompoundButton.OnCheckedChangeListener { override fun onCheckChanged(p0: CompoundButton?, p1: Boolean) { Log.d("test", "checkbox click") } } class MainActivity3 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(svaedInstanceState) val binding = ActivityMain3Binding.inflate(layoutInflater) setContentView(binding.root) /* ... */ binding.checkbox.setOnCheckedChangeListener(MyEventHandler()) } }
- SAM(single abstract method) 기법 이용 가능
class MainActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) /* ... */ val binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) /* ... */ binding.checkbox.setOnCheckedChangedListener { compoundButton, b -> Log.d("test", "checkbox click") } } }
뷰를 짧게 클릭할 때 발생하는 이벤트
뷰를 길게 클릭할 때 발생하는 이벤트
open fun setOnClickListener(l: View.OnClickListener?): Unit
open fun setonLongClickListener(l: View.OnLongClickListener?): Unit
binding.button.setOnClickListener {
Log.d("test", "click event")
}
binding.button.setOnLongClickListener {
Log.d("test", "Long click event")
true
}
// 롱클릭 이벤트 핸들러에서 true를 생략하면 오류 발생
// -> LongClickEvent의 콜백함수는
// abstract fun onLongClick(v: View!): Boolean 으로 정의되어 있음
// 반환값이 Boolean 타입이기 때문에 true나 false를 반환해야함
- 자바로 작성한 이벤트 핸들러
binding.btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { } });
- 코틀린으로 작성한 이벤트 핸들러
binding.btn.setOnClickListener(object: View.OnClickListener { override fun onClick(p0: View?) { } })
- SAM기법 사용
- 자바 인터페이스
public interface JavaInterface1 { void callback(); }
- 자바 함수
public class SAMTest { JavaInterface1 callback; public void setInterface(JavaInterface1 callback) { this.callback = callback; } }
- 코틀린에서 자바 함수 사용
자바 함수인 setInterface()를 코틀린에서 사용하려면 인터페이스를 구현한 객체를 매개변수로 지정해야 함
obj.setInterface(object: JavaInterface1 { override fun callback() { println("hello kotlin") } })
- SAM기법 사용으로 더 간결하게 작성
obj.setInterface { println("SAM") }
자바 인터페이스를 구현한 객체를 모두 SAM 기법으로 사용할 수는 없음
-> 추상 함수 하나를 포함하는 인터페이스만 가능
- SAM기법을 이용한 이벤트 핸들러 구조
binding.btn.setOnClickListener { ... }
Do it! 깡쌤의 안드로이드 프로그래밍 with 코틀린 (개정판)