Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
Expand Down Expand Up @@ -161,6 +162,16 @@ class KRRecyclerView : RecyclerView, IKuiklyRenderViewExport, NestedScrollingChi
*/
private var scrollWithParent = true

/**
* cache child View
*/
private var nestedChildView:KRRecyclerView? = null

/**
* cache child View
*/
private var nestedParentView:KRRecyclerView? = null

private var lastScrollParentX = 0

private var lastScrollParentY = 0
Expand Down Expand Up @@ -1371,7 +1382,7 @@ class KRRecyclerView : RecyclerView, IKuiklyRenderViewExport, NestedScrollingChi
var rv: KRRecyclerView? = null
var parent: ViewGroup? = parent as? ViewGroup
while (parent != null) {
if (parent is KRRecyclerView && !parent.directionRow && parent.directionRow == directionRow) {
if (parent is KRRecyclerView && !parent.directionRow && parent.directionRow == directionRow) {
rv = parent
break
}
Expand Down Expand Up @@ -1461,13 +1472,30 @@ class KRRecyclerView : RecyclerView, IKuiklyRenderViewExport, NestedScrollingChi
}

override fun onStartNestedScroll(child: View, target: View, axes: Int): Boolean {
return onStartNestedScroll(child, target, axes, ViewCompat.TYPE_TOUCH)
val accept = onStartNestedScroll(child, target, axes, ViewCompat.TYPE_TOUCH)
return accept
}

override fun onStartNestedScroll(
child: View, target: View, axes: Int,
type: Int
): Boolean {
val accept = handleStartNestedScroll(axes, type)
if (target is KRRecyclerView && accept){
nestedChildView = target
} else {
nestedChildView = null
}
return accept
}

/**
* 处理嵌套滚动开始事件
* @param axes 滚动轴向
* @param type 事件类型(Touch/Non-Touch)
* @return 是否接受嵌套滚动
*/
private fun handleStartNestedScroll(axes: Int, type: Int): Boolean {
if (!isScrollEnabled()) {
return false
}
Expand Down Expand Up @@ -1805,10 +1833,10 @@ class KRRecyclerView : RecyclerView, IKuiklyRenderViewExport, NestedScrollingChi
}

val shouldScrollParentY = when {
parentDy > 0 && target.scrollForwardMode == KRNestedScrollMode.PARENT_FIRST -> true
parentDy < 0 && target.scrollBackwardMode == KRNestedScrollMode.PARENT_FIRST -> true
parentDy > 0 && target.scrollForwardMode == KRNestedScrollMode.SELF_FIRST && !target.canScrollVertically(parentDy) -> true
parentDy < 0 && target.scrollBackwardMode == KRNestedScrollMode.SELF_FIRST && !target.canScrollVertically(parentDy) -> true
parentDy > 0 && target.scrollForwardMode == KRNestedScrollMode.PARENT_FIRST && !nestedParentCanScrollVerticallyFirst(parentDy)-> true
parentDy < 0 && target.scrollBackwardMode == KRNestedScrollMode.PARENT_FIRST && !nestedParentCanScrollVerticallyFirst(parentDy) -> true
parentDy > 0 && target.scrollForwardMode == KRNestedScrollMode.SELF_FIRST && !target.canNestedScrollVertically(parentDy) -> true
parentDy < 0 && target.scrollBackwardMode == KRNestedScrollMode.SELF_FIRST && !target.canNestedScrollVertically(parentDy) -> true
else -> false
}

Expand Down Expand Up @@ -1875,6 +1903,94 @@ class KRRecyclerView : RecyclerView, IKuiklyRenderViewExport, NestedScrollingChi
}
}

/**
* 判断当前父嵌套View是否能够滚动(根据scrollMode模式判断)
* @param parentDy 滚动方向,> 0 表示向前/向下,< 0 表示向后/向上
* @return 当前View是否能够滚动
*/
private fun nestedParentCanScrollVerticallyFirst(parentDy: Int): Boolean {
// 没有嵌套滚动父级,不能让父级滚动
if (!hasNestedScrollingParent()) {
Log.i("yich","【nestedParentCanScrollVerticallyFirst】not nest child this hashCode:${hashCode()}")
return false
}

// 查找父嵌套容器
val parentRecyclerView = findNestedParentRecyclerView()

// 根据滚动方向选择对应的scrollMode
val scrollMode = if (parentDy > 0) {
scrollForwardMode
} else {
scrollBackwardMode
}

Log.i("yich","【nestedParentCanScrollVerticallyFirst】nestedChild hashCode:${nestedChildView?.hashCode()} parentRecyclerView hashCode:${parentRecyclerView?.hashCode()} nestedChild hashCode:${nestedChildView?.hashCode()} scrollMode:${scrollMode} this hashCode:${this.hashCode()}")
// 根据模式判断父View是否应该滚动
return when (scrollMode) {
KRNestedScrollMode.SELF_ONLY -> {
// SELF_ONLY模式下,父View不参与嵌套滚动
false
}
KRNestedScrollMode.SELF_FIRST -> {
!canScrollVertically(parentDy)
}
KRNestedScrollMode.PARENT_FIRST -> {
// PARENT_FIRST模式下,父View优先滚动
parentRecyclerView?.canNestedScrollVertically(parentDy) ?: canScrollVertically(parentDy)
}
}
}

/**
* 查找最近的父嵌套RecyclerView(根据当前方向)
* @return 父RecyclerView,如果没有则返回null
*/
private fun findNestedParentRecyclerView(): KRRecyclerView? {
return if (directionRow) {
findClosestHorizontalRecyclerViewParent()
} else {
findClosestVerticalRecyclerViewParent()
}
}

/**
* 判断是否还能嵌套滚动(考虑子View的嵌套滚动模式)
* @param direction 滚动方向,> 0 表示向前/向下,< 0 表示向后/向上
* @return 是否还能在指定方向嵌套滚动
*/
fun canNestedScrollVertically(direction: Int): Boolean {
// 查找嵌套的子View
val nestedChild = nestedChildView
val canScrollSelf = canScrollVertically(direction)
if (nestedChild == null || !nestedChild.hasNestedScrollingParent()) {
// 没有嵌套子View,直接使用自身的滚动判断
Log.i("yich","[canNestedScrollVertically]self scroll canScrollSelf:${canScrollSelf} this hashCode:${this.hashCode()}")
return canScrollSelf
}

// 有嵌套子View,根据子View的滚动模式判断
val childMode = if (direction > 0) {
nestedChild.scrollForwardMode
} else {
nestedChild.scrollBackwardMode
}
Log.i("yich","[canNestedScrollVertically]childMode :${childMode} nestedChild hashCode:${nestedChild.hashCode()} this hashCode:${this.hashCode()}")
return when (childMode) {
KRNestedScrollMode.SELF_ONLY -> {
nestedChild.canScrollVertically(direction)
}
KRNestedScrollMode.SELF_FIRST -> {
// 先子View滚动,子View滚动到边界后父View才能滚动
canScrollSelf || nestedChild.canNestedScrollVertically(direction)
}
KRNestedScrollMode.PARENT_FIRST -> {
// 父View优先滚动,这里返回true允许父View处理
canScrollVertically(direction)
}
}
}

override fun getNestedScrollAxes(): Int {
return mNestedScrollAxesTouch or mNestedScrollAxesNonTouch
}
Expand Down
Loading