본문 바로가기

곳간에서 인심난다

[Android] Swipe 제스쳐 감지 CustomView

GestureDetector 이용

https://stackoverflow.com/a/19506010

 

Android: How to handle right to left swipe gestures

I want my app to recognize when a user swipes from right to left on the phone screen. How to do this?

stackoverflow.com

 

 

GestureDetector의 onFling()이 호출되지 않을 경우

https://stackoverflow.com/a/17833241

 

onfling() not being called for some reason

I'm trying to implement gesture in my app and for some reason the the onfling() is not being called. I tried reading numerous posts regarding this and tried fixing my code but it's not working . The

stackoverflow.com

 

 

class SwipeDetectorView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {

    private val gestureDetectorCompat = GestureDetectorCompat(context, SwipeDetectorListener())

    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        super.dispatchTouchEvent(event)
        return gestureDetectorCompat.onTouchEvent(event)
    }

    var swipeRightCallback: (() -> Unit)? = null

    var swipeLeftCallback: (() -> Unit)? = null

    fun onSwipeRight() {
        Timber.d("스와이프 onSwipeRight")
        swipeRightCallback?.invoke()
    }

    fun onSwipeLeft() {
        Timber.d("스와이프 onSwipeLeft")
        swipeLeftCallback?.invoke()
    }


    inner class SwipeDetectorListener : GestureDetector.SimpleOnGestureListener() {

        private val SWIPE_DISTANCE_THRESHOLD = 100
        private val SWIPE_VELOCITY_THRESHOLD = 100

        override fun onDown(e: MotionEvent): Boolean {
            return true
        }

        override fun onFling(
            e1: MotionEvent,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            val distanceX = e2.x - e1.x
            val distanceY = e2.y - e1.y
            if (abs(distanceX) > abs(distanceY) && abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && abs(
                    velocityX
                ) > SWIPE_VELOCITY_THRESHOLD
            ) {
                Timber.d("distanceX : $distanceX")
                if (distanceX > 0)
                    onSwipeRight()
                else
                    onSwipeLeft()
                return true
            }
            return false
        }
    }
}

 

스와이프 제스쳐를 입력받고자 하는 위치에 요 뷰를 올리면 된다.  


과제에서 스와프 제스쳐로 백 키 기능 요구하는 줄 알고 급하게 만든  커스텀 뷰. 다시 보니 테스트폰의 시스템에서 제공하는 기능이었다.  안도감과 이 포스트 글이 하나 남음.