본문 바로가기
안드로이드 코틀린

[Kotlin][Android] 터치 제스처 감지 (Gesture Detector)

by teamnova 2022. 8. 13.

안드로이드에서 터치 제스처를 감지하는 기능을 코틀린으로 구현하는 방법에 대해 알아보겠습니다. 

 

* 터치 제스처 종류

- onDown (터치)

 

- onShowPress (onDown 보다 길게 터치)

 

- onSingleTapUp (터치가 끝날 때)

 

- onLongPress (onShowPress보다 길게 터치)

 

- onScroll(스크롤)

 

- onFling (스크롤과 비슷하지만 손가락으로 튕길 때)

 

 

 

1. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity"
    android:gravity="center"
    android:padding="10dp">

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#FF9800" />

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <!-- 현재 터치 상태를 출력하기 위한 TextView-->
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#FFFFFFFF" />
    </ScrollView>
</LinearLayout>

상단 부분의 뷰는 터치를 감지하는 영역이고 

하단의 텍스트뷰는 어떤 터치인지 출력해주는 뷰입니다. 

 

 

 

2. MainActivity.java

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.ScrollView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    lateinit var view : View
    lateinit var scrollView : ScrollView
    lateinit var tv : TextView
    var detector: GestureDetector? = null //무슨 제스쳐를 했는지 감지

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        detector = GestureDetector(this, object : GestureDetector.OnGestureListener {
            //화면이 눌렸을 때
            override fun onDown(e: MotionEvent): Boolean {
                printString("onDown() 호출됨")
                return true
            }

            //화면이 눌렸다 떼어지는 경우
            override fun onShowPress(e: MotionEvent) {
                printString("onShowPress() 호출됨")
            }

            //화면이 한 손가락으로 눌렸다 떼어지는 경우
            override fun onSingleTapUp(e: MotionEvent): Boolean {
                printString("onSingleTapUp() 호출됨")
                return true
            }

            //화면이 눌린채 일정한 속도와 방향으로 움직였다 떼어지는 경우
            override fun onScroll(
                e1: MotionEvent,
                e2: MotionEvent,
                distanceX: Float,
                distanceY: Float
            ): Boolean {
                printString("onScroll() 호출됨 => $distanceX, $distanceY")
                return false
            }

            //화면을 손가락으로 오랫동안 눌렀을 경우
            override fun onLongPress(e: MotionEvent) {
                printString("onLongPress() 호출됨")
            }

            //화면이 눌린채 손가락이 가속해서 움직였다 떼어지는 경우
            override fun onFling(
                e1: MotionEvent,
                e2: MotionEvent,
                velocityX: Float,
                velocityY: Float
            ): Boolean {
                printString("onFling() 호출됨 => $velocityX, $velocityY")
                return true
            }
        })

        view = findViewById(R.id.view)
        scrollView = findViewById(R.id.scrollView)
        tv = findViewById(R.id.textView)

        view.setOnTouchListener { _, event ->
            detector!!.onTouchEvent(event)
        }
    }

    private fun printString(value: String) {
        //좌표 출력
        tv.append("$value \n") //한 줄씩 추가

        //자동으로 마지막 줄로 스크롤 내림
        scrollView.fullScroll(View.FOCUS_DOWN)
    }

}

GestureDetector.OnGestureListener에 필요한 로직을 추가하고 

뷰에 터치리스너를 달고 발생하는 이벤트를 Detector 객체에 전달해줍니다.

 

 

 

3. 시현 영상