화면을 터치하면 이벤트라는 것이 발생하게 되는데 이 이벤트는 리스너라는 것을 이용하여 다룰 수 있습니다.

 

 

터치 이벤트 이외에도 단말의 방향을 가로 방향으로 돌렸을 때도 이벤트가 발생하고 키패드에서 키를 하나 눌렀을 때도 이벤트가 발생합니다.

 

 

이런 이벤트를 어떻게 처리할 수 있는지 알아봅시다.

 

 

버튼을 클릭했을 때 버튼 클릭한 것을 이벤트라고 하는 걸로 만들어서 전달받을 수 있습니다.

전달받아서 처리할 수 있는데 이것을 이벤트 리스너라고 하는걸 등록해서 처리할 수 있습니다.

이게 버튼뿐만 아니라 뷰라고 하는 거에 대해서 거의 대부분 다 적용할 수 있습니다.

 

 

그래서 기본적인 이벤트 처리방법을 이해하면 굉장히 다양한 기능을 만들 수 있습니다.

 

 

이벤트는 가장 단순한게 버튼을 클릭했을 때를 생각해볼 수 있습니다.

버튼을 클릭하면 onClick이라는 이벤트가 발생됩니다. 그래서 그때 이 버튼에다가 OnClickListener라고 하는 리스너를 설정하면 이쪽으로 이벤트를 전달해줍니다. 

 

 

그런데 이 클릭은 좀 더 세분화해보면 터치 이벤트로 나눠볼 수 있습니다.

사용자가 스마트폰 단말의 화면에다가 손가락으로 터치를 하면 손가락으로 누를 때, 누른 상태에서 움직일 때, 손가락을 뗐을 때로 구분할 수 있습니다. 

 

 

그 다음에 키패드에서 키를 하나 눌렀을 때 우리가 어떤 키를 눌렀는지 확인할 수 있는 방법도 있습니다. 그리고 손가락을 눌러서 끌어당길 때 그 때 빨리할 수도 있고 느리게 할 수도 있을텐데 그런 것들을 빨리하거나 느리게 할 때 얼마나 빨리했는지 이런것들을 일일이 계산해야 하는데 제스처라고 하는걸 쓰면 계산하는 걸 알아서 내부에서 해줍니다.

 

 

그래서 제스처 이벤트라고 하는걸 처리하는 방법이 있습니다.

 

 

뷰마다 포커스가 주어질 수 있는데 이건 실제로 쓰는 경우는 쓰게 될 일은 많지 않지만 포커스라고 하는게 있습니다.

그리고 단말의 방향을 가로로 돌렸을 때 그때 받을 수 있는 이벤트도 있습니다.

 

 

그럼 간단히 뷰를 터치했을 때 발생하는 터치 이벤트에 대한 터치 이벤트 리스너를 만들어보겠습니다.

view에 onTouchListener를 만들어줍니다. 그러면 event.action으로 터치 정보가 넘어오고 MotionEvent를 이용해 각각의 상태를 구분할 수 있습니다. 그리고 마지막에 true로 정상적으로 처리됐음을 알려줍니다.

view.setOnTouchListener { v, event ->
    var action = event.action

    val curX = event.x
    val curY = event.y

    if (action == MotionEvent.ACTION_DOWN) {
        println("손가락 눌렸음 : $curX, $curY")
    } else if (action == MotionEvent.ACTION_MOVE) {
        println("손가락 움직임 : $curX, $curY")
    } else if (action == MotionEvent.ACTION_UP) {
        println("손가락 떼졌음 : $curX, $curY")
    }

    true
}

 

그럼 직접 터치하면 엄청 많이 호출되는 것을 볼 수 있습니다. 근데 이 엄청 많이 호출되는 것을 일일이 이게 얼마나 빠른 속도로 움직이냐라고 하는걸 가지고 기능을 만들어야 될 때가 있는데 일일이 하기 힘드니까 제스처라고 하는걸 가지고 자동으로 계산되게 만들 수 있습니다.

 

 

그럼 이번에는 제스처디텍터라는 것을 만들어 view2의 영역에서 테스트를 해보겠습니다.

detector = GestureDetector(
    this, object: GestureDetector.OnGestureListener {
        override fun onDown(e: MotionEvent?): Boolean {
            println("onDown() 호출됨")
            return true
        }

        override fun onShowPress(e: MotionEvent?) {
            println("onShowPress() 호출됨")
        }

        override fun onSingleTapUp(e: MotionEvent?): Boolean {
            println("onSingleTapUp() 호출됨")
            return true
        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent?,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            println("onFling() 호출 됨 : $velocityX, $velocityY")
            return true
        }

        override fun onScroll(
            e1: MotionEvent?,
            e2: MotionEvent?,
            distanceX: Float,
            distanceY: Float
        ): Boolean {
            println("onScroll() 호출됨 : $distanceX, $distanceY")
            return true
        }

        override fun onLongPress(e: MotionEvent?) {
            println("onLongPress() 호출됨")
        }
    })

view2.setOnTouchListener { v, event ->
    detector.onTouchEvent(event)
    true
}

 

이렇게 제스처디텍터를 사용하면 좀 더 편하게 처리할 수 있는 기능이 생깁니다. 예를들어 갤러리에서 사진을 볼 때 다음 사진을 보기위해 사진을 옆으로 스크롤해 넘길 때 끝까지 넘기는게 아니라 어느정도 넘기면 옆으로 탁 튕기면서 들어가는데 이 때 제스처이벤트를 사용하면 훨씬 쉽게 그런 기능을 구현할 수 있습니다. 

 

 

이번에는 키 이벤트에 대해서 알아보겠습니다.

키는 키패드를 얘기합니다. 키패드를 누르면 KEYCODE_HOME, KEYCODE_BACK, KEYCODE_1 등과 같은 키 값이 들어옵니다. 그래서 이 키 값을 전달받아서 처리하고 싶으면 onKeyDown이라던가 onKey와 같은 메서드를 재정의해서 사용하면 됩니다.  그럼 키 이벤트를 처리하는 코드를 만들어 보겠습니다.

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        toast("시스템 BACK 버튼 눌림")
        return true
    }
    return false
}

시스템 BACK키를 누르면 원래 화면이 없어지는데 이렇게하면 화면이 안없어지도록 만들 수 있습니다.

그래서 '한번 더 누르면 종료됩니다' 하는 메세지를 보여주는 그런 앱들을 볼 수 있습니다.

 

 

만든 코드는 아래에 첨부했습니다.

activity_my_event.xml

MyEvent.kt

Reference

 

 

+ Recent posts