简体   繁体   English

带有 onTouch 的自定义视图不会平滑滑动

[英]Custom view with onTouch doesn't fling smoothly

I've made a simple class with gestures and I use it in a view.我用手势制作了一个简单的类,并在视图中使用它。

I'm trying to do a simple swipe to dismiss effect but in the end, it's not that smooth.我正在尝试做一个简单的滑动来消除效果,但最后,它并不是那么顺利。 the translation is great but when the finger release happens, the velocity from the onFling function looks wrong..翻译很棒,但是当手指松开时,onFling 函数的速度看起来不对。

class SwipeGestureListener : SimpleOnGestureListener, OnTouchListener {
    var context: Context? = null

    lateinit var flingDetector: GestureDetector

    lateinit var flingY: FlingAnimation
    lateinit var springBackTranslationYAnimation: SpringAnimation

    var lastY = 0f

    val minDistanceUp = 40
    val friction = 0.1f
    var minFlingArea = 0f
    var isItUpDirection = false

    constructor(
        context: Context?,
        dialog: View?
    ) {

        this.context = context

        dialog?.let {
            it.viewTreeObserver
                ?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                    override fun onGlobalLayout() {
                        minFlingArea = -(it.height + it.top).toFloat() - 100f
                        it.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    }
                })
        }

        flingDetector = GestureDetector(context, flingListener)

        springBackTranslationYAnimation = SpringAnimation(dialog,
            object : FloatPropertyCompat<View>("translationY") {
                override fun getValue(view: View): Float {
                    return view.translationY
                }

                override fun setValue(
                    view: View,
                    value: Float
                ) {
                    view.translationY = value
                }
            })

        val springForceY = SpringForce(0f)
        springForceY.stiffness = SpringForce.STIFFNESS_VERY_LOW
        springForceY.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
        springBackTranslationYAnimation.spring = springForceY
        springBackTranslationYAnimation.addUpdateListener(dynamicAnimationCallback())

        flingY = FlingAnimation(dialog, DynamicAnimation.TRANSLATION_Y)
    }

    private val flingListener: GestureDetector.OnGestureListener =
        object : SimpleOnGestureListener() {
            override fun onDown(e: MotionEvent?): Boolean {
                return true
            }

            override fun onFling(
                downEvent: MotionEvent,
                moveEvent: MotionEvent,
                velocityX: Float,
                velocityY: Float
            ): Boolean {

                val distanceY = downEvent.rawY - moveEvent.rawY

                if (distanceY >= minDistanceUp && isItUpDirection) {

                    flingY.setStartVelocity(if (velocityY > 0) -(velocityY) else velocityY)
                        .setMinValue(minFlingArea)
                        .setFriction(friction)
                        .start()
                } else {
                    springBackTranslationYAnimation.start()
                }

                return true
            }
        }

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        view.performClick()

        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {

                flingY.cancel()
                springBackTranslationYAnimation.cancel()
            }
            MotionEvent.ACTION_MOVE -> {

                val deltaY = event.rawY - lastY

                view.translationY = deltaY + view.translationY

                isItUpDirection = event.rawY < lastY
            }
            MotionEvent.ACTION_UP -> {

                if (!isItUpDirection) {
                    springBackTranslationYAnimation.start()
                }
            }
        }

        lastY = event.rawY

        flingDetector.onTouchEvent(event)

        return true
    }
}

Any idea what's wrong here?知道这里有什么问题吗?

Thanks in advance!提前致谢!

I have implemented gesture for swipe left and swipe right.Please try this one.我已经实现了向左滑动和向右滑动的手势。请试试这个。

import android.content.Context
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener

open class OnSwipeTouchListener(ctx: Context) : OnTouchListener {

val gestureDetector: GestureDetector

companion object {

    private val SWIPE_THRESHOLD = 100
    private val SWIPE_VELOCITY_THRESHOLD = 100
}

init {
    gestureDetector = GestureDetector(ctx, GestureListener())
}

override fun onTouch(v: View, event: MotionEvent): Boolean {


    var isTouch = false

    if (gestureDetector != null && event != null) {

        isTouch = gestureDetector.onTouchEvent(event)
    } else {
        isTouch = true
    }

    return isTouch

}

inner class GestureListener : SimpleOnGestureListener() {

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

    override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
        var result = false
        try {


            val diffY = e1?.y?.let { e2?.y?.minus(it) }
            val diffX = e1?.x?.let { e2?.x?.minus(it) }

            if (diffX != null && diffY != null) {

                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight()
                        } else {
                            onSwipeLeft()
                        }
                        result = true
                    }
                } else {

                }
            } else {
                onSwipeRight()

                result = true
            }


            /*else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
               if (diffY > 0) {
                   onSwipeBottom()
               } else {
                   onSwipeTop()
               }
               result = true
           }*/
        } catch (exception: Exception) {
            exception.printStackTrace()
        }

        return result
    }


}

open fun onSwipeRight() {}

open fun onSwipeLeft() {}

open fun onSwipeTop() {}

open fun onSwipeBottom() {}

open fun onSwipeDown() {

 }
}

Call from your view从您的角度呼叫

     view?.setOnTouchListener(object : OnSwipeTouchListener(it) {

            override fun onTouch(v: View, event: MotionEvent): Boolean {


                return super.onTouch(v, event)
            }


            override fun onSwipeDown() {

                super.onSwipeDown()
            }

            override fun onSwipeRight() {


            }     
            override fun onSwipeLeft() {
                super.onSwipeLeft()


                        }

                    }
                }
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM