뷰 이벤트
- 뷰에서 일어난 이벤트 처리
이벤트 소스 : 이벤트가 발생한 객체
이벤트 핸들러 : 이벤트 발생 시 실행할 로직이 구현된 객체
리스너 : 이벤트 소스와 이벤트 핸들러를 연결해주는 함수
이벤트 리스너는 이벤트 핸들러를 이벤트 소스와 연결해준다.
- 대부분 이벤트 핸들러는 이름 형식이
On___Listner인 인터페이스를 구현해서 만든다. 이 인터페이스 구현하는 방식이 여러개임
1. 이벤트 리스너에서 바로 핸들러 연결
- 이벤트 리스너에서 바로 인터페이스 상속받아서 핸들러 구현
binding.checkbox.setOnCheckedChangeListner(object : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1:Boolean){
Log.d("check", "클릭")
}
})
2. 액티비티 자체에서 인터페이스 구현
- MainActivity 에서 바로 인터페이스 상속받아서 핸들러 구현
class MainActivity : AppCompatActivity(), CompoundButton.OnCheckedChangeListener {
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener(this)
}
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean){
Log.d("check", "체크박스 클릭")
}
}
3. 이벤트 핸들러를 별도의 클래스로 만들어서 처리
- class에서 바로 인터페이스 상속받아서 핸들러 구현
class MyEventHandler : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean){
Log.d("check", "클릭")
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
val binding = ActivitiMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener(MyEventHandler())
}
}
4. 코틀린 SAM 기법 사용
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstancesState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox.setOnCheckedChangeListener {
compoundButton, b ->
Log.d("check", "클릭")
}
}
....
예제 코드
- 스톱워치 만들기 예제에서는 리스너 인터페이스를 구현하여 핸들러로 사용하지 않고, 핸들할 내용을 직접 적었다.
binding.stopButton.setOnClickListener {
pauseTime = binding.chronometer.base - SystemClock.elapsedRealtime()
binding.chronometer.stop()
binding.stopButton.isEnabled = false
binding.resetButton.isEnabled = true
binding.startButton.isEnabled = true
}
- 그래서 헷갈렸는데 지금까지 이해한 바로는 SetOn---Listener 라는 리스너에서 On---Listener라는 인터페이스를 구현해서 핸들할 수도 있고, 구현 안하고 바로 핸들할 내용을 처리할 수도 있다.
- 하나의 override한 함수로 여러 뷰를 처리하고 싶을 때 리스너 인터페이스를 구현하여 처리하는 듯 하다.
(예시) - 2번 경우를 여러개 묶음
class MainActivity : AppCompatActivity(), CompoundButton.OnCheckedChangeListener {
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.checkbox1.setOnCheckedChangeListener(this)
binding.checkbox2.setOnCheckedChangeListener(this)
binding.checkbox3.setOnCheckedChangeListener(this)
}
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean){
if (p0!!=null){
when (p0.id) {
R.id.checkbox1 -> Log.d("check1", "체크1")
R.id.checkbox2 -> Log.d("check2", "체크1")
R.id.checkbox3 -> Log.d("check3", "체크1")
}
}
}
}