【发布时间】:2018-11-27 08:59:32
【问题描述】:
我在垂直 RecyclerView 中有水平 recyclerViews。 要水平滚动,我应该从 45 度滑动到 -45 度。从 90 度垂直滚动到 45 度。有没有可能覆盖这个?
例如,垂直滚动仅适用于从 105 到 75 度的滑动。否则,水平滚动。
【问题讨论】:
标签: android android-recyclerview
我在垂直 RecyclerView 中有水平 recyclerViews。 要水平滚动,我应该从 45 度滑动到 -45 度。从 90 度垂直滚动到 45 度。有没有可能覆盖这个?
例如,垂直滚动仅适用于从 105 到 75 度的滑动。否则,水平滚动。
【问题讨论】:
标签: android android-recyclerview
你需要像这样创建MainVerticalRecyclerView:
open class MainVerticalRecyclerView : RecyclerView {
private var scrollPointerId = -1
private var pointTouchX = 0
private var pointTouchY = 0
private var touchSlopType = 0
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
val vc = ViewConfiguration.get(context)
touchSlopType = vc.scaledTouchSlop
}
override fun setScrollingTouchSlop(slopConstant: Int) {
super.setScrollingTouchSlop(slopConstant)
val vc = ViewConfiguration.get(context)
when (slopConstant) {
TOUCH_SLOP_DEFAULT -> touchSlopType = vc.scaledTouchSlop
TOUCH_SLOP_PAGING -> touchSlopType = vc.scaledPagingTouchSlop
}
}
override fun onInterceptTouchEvent(e: MotionEvent?): Boolean {
if (e == null) {
return false
}
val action = e.actionMasked
val actionIndex = e.actionIndex
when (action) {
MotionEvent.ACTION_DOWN -> {
scrollPointerId = e.getPointerId(0)
pointTouchX = Math.round(e.x + 0.5f)
pointTouchY = Math.round(e.y + 0.5f)
return super.onInterceptTouchEvent(e)
}
MotionEvent.ACTION_POINTER_DOWN -> {
scrollPointerId = e.getPointerId(actionIndex)
pointTouchX = Math.round(e.getX(actionIndex) + 0.5f)
pointTouchY = Math.round(e.getY(actionIndex) + 0.5f)
return super.onInterceptTouchEvent(e)
}
MotionEvent.ACTION_MOVE -> {
val index = e.findPointerIndex(scrollPointerId)
if (index < 0) {
return false
}
val x = Math.round(e.getX(index) + 0.5f)
val y = Math.round(e.getY(index) + 0.5f)
if (scrollState != SCROLL_STATE_DRAGGING) {
val dx = x - pointTouchX
val dy = y - pointTouchY
var startScroll = false
if (layoutManager?.canScrollHorizontally() == true && Math.abs(dx) > touchSlopType && (layoutManager?.canScrollVertically() == true || Math.abs(dx) > Math.abs(dy))) {
startScroll = true
}
if (layoutManager?.canScrollVertically() == true && Math.abs(dy) > touchSlopType && (layoutManager?.canScrollHorizontally() == true || Math.abs(dy) > Math.abs(dx))) {
startScroll = true
}
return startScroll && super.onInterceptTouchEvent(e)
}
return super.onInterceptTouchEvent(e)
}
else -> {
return super.onInterceptTouchEvent(e)
}
}
}
}
并为其他嵌套在主RecyclerView 内的RecyclerView 创建ChildHorizontalRecyclerView,如下所示:
class ChildHorizontalRecyclerView : MainVerticalRecyclerView {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}
如果您想在触摸PlayStore 时像PlayStore 一样滚动,则需要写:
recyclerView.addOnItemTouchListener(object : RecyclerView.OnItemTouchListener {
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
if (e.action == MotionEvent.ACTION_DOWN && rv.scrollState == RecyclerView.SCROLL_STATE_SETTLING) {
rv.stopScroll()
}
return false
}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
})
【讨论】: