1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
import android.support.v4.view.NestedScrollingChild
import android.support.v4.view.NestedScrollingChildHelper
import android.support.v4.view.ViewCompat
import android.util.AttributeSet
import android.view.MotionEvent
import android.webkit.WebView
/**
* Created by Allan Wang on 20/12/17.
*
* Webview extension that handles nested scrolls
*/
open class NestedWebView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr), NestedScrollingChild {
private lateinit var childHelper: NestedScrollingChildHelper
private var lastY: Int = 0
private val scrollOffset = IntArray(2)
private val scrollConsumed = IntArray(2)
private var nestedOffsetY: Int = 0
init {
init()
}
fun init() {
// To avoid leaking constructor
childHelper = NestedScrollingChildHelper(this)
}
/**
* Handle nested scrolling against SwipeRecyclerView
* Courtesy of takahirom
*
* https://github.com/takahirom/webview-in-coordinatorlayout/blob/master/app/src/main/java/com/github/takahirom/webview_in_coodinator_layout/NestedWebView.java
*/
@SuppressLint("ClickableViewAccessibility")
final override fun onTouchEvent(ev: MotionEvent): Boolean {
val event = MotionEvent.obtain(ev)
val action = event.action
if (action == MotionEvent.ACTION_DOWN)
nestedOffsetY = 0
val eventY = event.y.toInt()
event.offsetLocation(0f, nestedOffsetY.toFloat())
val returnValue: Boolean
when (action) {
MotionEvent.ACTION_MOVE -> {
var deltaY = lastY - eventY
// NestedPreScroll
if (dispatchNestedPreScroll(0, deltaY, scrollConsumed, scrollOffset)) {
deltaY -= scrollConsumed[1]
event.offsetLocation(0f, -scrollOffset[1].toFloat())
nestedOffsetY += scrollOffset[1]
}
lastY = eventY - scrollOffset[1]
returnValue = super.onTouchEvent(event)
// NestedScroll
if (dispatchNestedScroll(0, scrollOffset[1], 0, deltaY, scrollOffset)) {
event.offsetLocation(0f, scrollOffset[1].toFloat())
nestedOffsetY += scrollOffset[1]
lastY -= scrollOffset[1]
}
}
MotionEvent.ACTION_DOWN -> {
returnValue = super.onTouchEvent(event)
lastY = eventY
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
returnValue = super.onTouchEvent(event)
stopNestedScroll()
}
else -> return false
}
return returnValue
}
/*
* ---------------------------------------------
* Nested Scrolling Content
* ---------------------------------------------
*/
final override fun setNestedScrollingEnabled(enabled: Boolean) {
childHelper.isNestedScrollingEnabled = enabled
}
final override fun isNestedScrollingEnabled() = childHelper.isNestedScrollingEnabled
final override fun startNestedScroll(axes: Int) = childHelper.startNestedScroll(axes)
final override fun stopNestedScroll() = childHelper.stopNestedScroll()
final override fun hasNestedScrollingParent() = childHelper.hasNestedScrollingParent()
final override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?) = childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow)
final override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) = childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
final override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) = childHelper.dispatchNestedFling(velocityX, velocityY, consumed)
final override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) = childHelper.dispatchNestedPreFling(velocityX, velocityY)
}
|