OnTouchListerner не должен интерпретировать пролистывания, чтобы открыть DrawerLayout как Long Click - PullRequest
0 голосов
/ 10 ноября 2018

Я обнаруживаю клики в своем окне повторного использования, используя класс OnItemTouchListener, приведенный ниже. К сожалению, это не работает при использовании DrawerLayout. Если я проведу пальцем, чтобы открыть DrawerLayout/NavigationView, мой OnItemTouchListener тоже получит это событие и выполнит действие onLongClick.

Этого не произойдет, если я использую ViewHolders '1007 *. В чем маленький секрет, OnLongClickListener Views проверяет перед запуском LongClick-события, чтобы обнаружить, что действие перетаскивания - это не длинный щелчок, а жест, чтобы открыть ящик?

class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener {

    //region Variables

    private val gestureDetector: GestureDetector

    //endregion

    init {
        gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapUp(e: MotionEvent?): Boolean {
                return true
            }

            override fun onLongPress(e: MotionEvent?) {
                val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)

                if (child != null) {
                    onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)
                }

                super.onLongPress(e)
            }
        })
    }

    //region TouchHandler

    override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
        val child = rv.findChildViewUnder(e.x, e.y)

        if (child != null && gestureDetector.onTouchEvent(e)) {
            onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)
        }

        return false
    }

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {

    }

    override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {

    }

    //endregion

    interface ItemTouchListener {
        fun onItemClick(view: View, pos: Int, e: MotionEvent)
        fun onItemLongClick(view: View, pos: Int, e: MotionEvent)
    }

    companion object {
        fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean {
            val view = container.findViewById<View>(viewId)

            val rect = Rect()
            view.getGlobalVisibleRect(rect)

            return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())
        }
    }
}

1 Ответ

0 голосов
/ 13 ноября 2018

Я решил это следующим образом:

gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
    private val MIN_SWIPE_DISTANCE: Int = 50
    private lateinit var downMotionEvent: MotionEvent

    override fun onDown(e: MotionEvent?): Boolean {
        e?.let { downMotionEvent = it }

        return super.onDown(e)
    }

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

    override fun onLongPress(e: MotionEvent?) {
        e?.let {
            val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

            if (child != null && !isGestureSwipe(it)) {
                onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)
            }
        }

        super.onLongPress(e)
    }

    fun isGestureSwipe(e: MotionEvent): Boolean {
        return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE
    }
})
...