이번 캠프의 최종 프로젝트를 완성해가면서 특정 버튼들의 경우 중복 클릭이 되면 문제가 되는 경우가 생겼다는걸 인지하고 그 특정 버튼들에 중복 클릭 방지 처리를 하기로했다.
버튼 중복 클릭을 방지하기 위한 방법으로는 버튼의 Enabled = false로 만든다거나 버튼 클릭시 최상단에 로딩을 보여준다거나 등등 여러가지 방법이 있겠지만, 내가 이번 프로젝트에 사용한 방법은 한번 클릭하면 일정시간동안 클릭 자체를 막아버리는 방법을 사용해서 버튼의 중복 클릭을 방지했다.
abstract class OnSingleClickListener: View.OnClickListener {
private var lastClickTime = 0L
abstract fun onSingleClick(v: View?)
override fun onClick(v: View?) {
val currentClickTime = System.currentTimeMillis()
val checkTime = currentClickTime - lastClickTime
lastClickTime = currentClickTime
// 중복클릭이 아닌경우 onSingleClick 실행
if (checkTime > 1500L) {
onSingleClick(v)
}
}
}
// setOnClickListener 설정
binding.btnToggleQuestState.setOnClickListener(object : OnSingleClickListener() {
override fun onSingleClick(v: View?) {
mainViewModel.togglePlay()
}
})
카메라 촬영 버튼의 경우 touchListener를 사용해서 ACTION_DOWN과 ACTION_UP 상태일 때 백그라운드를 다르게 지정해주었다.
abstract class OnSingleTouchListener: View.OnTouchListener {
private var lastTouchTime = 0L
abstract fun onSingleTouchUp(v: View, event: MotionEvent)
abstract fun onSingleTouchDown(v: View, event: MotionEvent)
override fun onTouch(v: View, event: MotionEvent): Boolean {
val currentTouchTime = System.currentTimeMillis()
val checkTime = currentTouchTime - lastTouchTime
lastTouchTime = currentTouchTime
when(event.action) {
MotionEvent.ACTION_DOWN -> {
if (checkTime > 3000L) onSingleTouchDown(v, event)
}
MotionEvent.ACTION_UP -> onSingleTouchUp(v, event)
}
return true
}
}
// setOnTouchListener 설정
binding.btnCapture.apply {
setOnTouchListener(object : OnSingleTouchListener() {
override fun onSingleTouchUp(v: View, event: MotionEvent) {
playWithMediaPlayer()
this@apply.load(R.drawable.btn_capture_click)
mediaActionSound.play(MediaActionSound.SHUTTER_CLICK)
cameraHandler.capturePhoto(imageCaptureCallback())
}
override fun onSingleTouchDown(v: View, event: MotionEvent) {
this@apply.load(R.drawable.btn_capture)
v.performClick()
}
})
}
버튼 중복클릭 방지를 하면서 처음에 Enabled 값을 조정하는 방법만 생각했는데 찾아보니 여러가지 방법이 있었고 찾아본 방법중에 가장 프로젝트에 적합하다고 생각하는 방법을 채택했다. 다시한번 추상클래스에 대해서 생각해볼 수 있는 기회였고 많이 써보지못한 추상클래스를 써볼 수 있어서 좋았다.