【问题标题】:Android ScrollView inside RecyclerView.ViewHolder: prevent ItemTouchHelper from getting touch event?RecyclerView.ViewHolder中的Android ScrollView:防止ItemTouchHelper获取触摸事件?
【发布时间】:2020-01-09 15:23:58
【问题描述】:

设置:我有一个RecyclerView 和一个vertical LinearLayoutManager。每个ViewHolder有2个TextViews(图中绿色和红色),可以很长。由于HorizontalScrollViewRED 可以水平滚动。由于ScrollViewGREEN 可以垂直滚动。

现在我实现了ItemTouchHelper,可以向左、向上或向下滑动。问题是我的ScrollViews 不再工作了。相反,即使我向上或向下滑动GREEN,移动的是我的ViewHolder如何防止我的ItemTouchHelper 获得触摸事件?

我试过了:

-android:descendantFocusability="blocksDescendants"

-NestedScrollView 而不是ScrollView

-在我的适配器内部实现setOnTouchListener以返回true(监听器被触发,但事件未被消费)

-考虑在onChildDraw 中使用RecyclerView.findChildViewUnder 手动滚动并阻止super 方法,但我找不到获取坐标的方法

到目前为止没有任何效果。我该怎么做呢?这是我的ItemTouchHelper

private fun enableSwipe() {
        val simpleItemTouchCallback =
            object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.ACTION_STATE_IDLE, ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT) {

            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean {
                return false
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                val position = viewHolder.adapterPosition

                if (direction == ItemTouchHelper.LEFT) {
                    val content = mAdapter.getContentForPosition(position)

                    //do stuff...
                }
            }

            override fun onChildDraw(
                c: Canvas,
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                actionState: Int,
                isCurrentlyActive: Boolean
            ) {

                val mdX = if (abs(dY) > abs(dX)) {
                    0f
                }else{
                    dX
                }
                val mdY = if (abs(dY) > abs(dX)) {
                    when{
                        dY > 0 ->  if (dY > 500f) 500f else dY
                        else -> if (dY < -500f) -500f else dY
                    }

                }else{
                    0f
                }
                //override viewHolder in case we swipe up or down on the other content
                val mViewHolder: RecyclerView.ViewHolder = if (abs(dY) > abs(dX)) {
                            if (dY < 0) {
                                //swiping up
                                getViewHolder(1) ?: viewHolder
                            } else {
                                getViewHolder(0) ?: viewHolder
                            }
                        }else {
                    viewHolder
                }

                super.onChildDraw(c, recyclerView, mViewHolder, mdX, mdY, actionState, isCurrentlyActive)
            }
        }
    val itemTouchHelper = ItemTouchHelper(simpleItemTouchCallback)
    itemTouchHelper.attachToRecyclerView(recyclerViewClash)
}

【问题讨论】:

    标签: android scrollview itemtouchhelper


    【解决方案1】:

    这是唯一有效的,终于找到了。重要的是要了解ItemTouchHelper 将实现onItemTouchListener

    OnItemTouchListener 允许应用程序在 RecyclerView 的视图层次结构级别拦截正在进行的触摸事件在将这些触摸事件考虑为 RecyclerView 自身的滚动行为之前

    textView.setOnTouchListener { v, event ->
            //let the scrollView handle the scroll event
            scrollView.onTouchEvent(event)
            //this is the key feature
            v.parent.requestDisallowInterceptTouchEvent(true)
            //return true to consume the event (mandatory)
            true
    }
    

    不需要其他任何东西。另外,ScrollView 就足够了,不需要NestedScrollView

    【讨论】:

    • 您能否更具体地说明在何处实现代码
    • @TejasSherdiwala 在 RecyclerView 的适配器中。这是一个包裹在 ScrollView 中的 TextView
    • 此解决方案禁用轻弹滚动。您实际上必须一直滚动内容直到结束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2012-06-10
    • 2016-07-17
    • 1970-01-01
    相关资源
    最近更新 更多