Пользовательский вид с onTouch не работает гладко - PullRequest
0 голосов
/ 10 января 2020

Я сделал простой класс с помощью жестов, и я использую его в виде.

Я пытаюсь сделать простое движение, чтобы отклонить эффект, но, в конце концов, это не так гладко. перевод отличный, но когда происходит отпускание пальца, скорость от функции 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
    }
}

Есть идеи, что здесь не так?

Заранее спасибо!

1 Ответ

0 голосов
/ 10 января 2020

Я реализовал жест для пролистывания влево и пролистывания вправо. Пожалуйста, попробуйте это.

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() {

 }
}

Звоните с вашего взгляда

     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()


                        }

                    }
                }
            }
        }
...