【发布时间】:2018-12-03 22:24:52
【问题描述】:
有一个 RecycleView,它有几个项目,其中之一是一个包含 WebView 的视图。在 WebView 内部,它加载了一个 html,并且有一个 iframe,其中有一个 html 表格内容,并且可以垂直滚动(包含的 div 的固定高度小于表格的高度)。
RecyclerView 似乎存在问题,它没有将触摸事件传递给 WebView。
这是怎么回事:
触摸屏拖动时,recycleView的onInterceptTouchEvent()先return false at ACTION_DOWN再return true when the event is MotionEvent.ACTION_MOVE。这个return true 将向目标子视图发送 MotionEvent.Cancel,以及所有进一步
事件将被传递到 RecycleView 的 onTouchEvent()
TestDerivedRecycleView:onInterceptTouchEvent(), return: false
event: MotionEvent { action=ACTION_DOWN, actionButton=0... }, this.scrollState: 0
TestDerivedRecycleView:onInterceptTouchEvent(), return: true
event: MotionEvent { action=ACTION_MOVE, actionButton=0... }, this.scrollState: 1
所以我创建了一个派生的 RecycleView,当目标视图上的事件是 ACTION_MOVE 时是 WebView 然后return false to let WebView handle the drag/move。
它正在部分工作。由于 webView 可能有一些其他的内容,例如文本区域。如果触摸该文本区域,则它是不可滚动的,因此回收视图将不会滚动。仅当触摸并拖动该表格元素时,表格元素才会滚动表格内容。
所需的行为应该是当拖动 RecyclerView 上的任何项目时,RecyclerView 应该向上滚动项目,只有当拖动该可滚动表格元素时,如果表格底部未显示,表格应该滚动其内容。
当 webview 是 RecycleView 的子项时,如何使 webview 的内容滚动工作?
class TestDerivedRecycleView : RecyclerView {
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
override fun onTouchEvent(event: MotionEvent): Boolean {
val ret = super.onTouchEvent(event)
Log.d("+++", "+++ TestDerivedRecycleView:onTouchEvent(), ret: $ret" +
"\nevent.action: ${event.action}, " +
"\nevent: $event" +
"\nthis: ${this}")
return ret
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
val ret = super.onInterceptTouchEvent(event)
val myCell = findChildViewUnder(event.x, event.y)
Log.w("+++", "+++ TestDerivedRecycleView:onInterceptTouchEvent(), ret: $ret" +
"\nmyCell: $myCell"+
"\n event.action: ${event.action}, this.scrollState: ${this.scrollState}" +
"\nevent: $event"+
"\nthis: $this")
// when the event is ACTION_MOVE and is touched on the WebView then return false to let WebView handle the event
if (
(myCell is ArticleWebView) &&
event.action == MotionEvent.ACTION_MOVE
&& this.scrollState == RecyclerView.SCROLL_STATE_DRAGGING
) {
Log.e("+++", "+++ TestDerivedRecycleView:onInterceptTouchEvent(), (myCell is WebView) return false")
return false
}
return ret
}
}
【问题讨论】:
标签: scroll android-recyclerview android-webview touch-event