diff options
author | Daniel Schaal <daniel@schaal.email> | 2021-07-04 07:00:06 +0300 |
---|---|---|
committer | Daniel Schaal <daniel@schaal.email> | 2021-07-04 07:36:07 +0300 |
commit | 783b29f37fd3a09ceb0fffbd9944e2131d2d4bb6 (patch) | |
tree | e97833d36b6f8c38ebe83c84e27a1c8538217b94 /app | |
parent | 39fe724923fe4b5aa7dfcbdc81fe33dbaf08dedc (diff) |
Switch NestedScrollWebView implementation
Enable toolbar scrolling in Pager activity
Diffstat (limited to 'app')
-rw-r--r-- | app/src/main/java/email/schaal/ocreader/view/NestedScrollWebView.kt | 162 | ||||
-rw-r--r-- | app/src/main/res/layout/toolbar_pager.xml | 1 |
2 files changed, 99 insertions, 64 deletions
diff --git a/app/src/main/java/email/schaal/ocreader/view/NestedScrollWebView.kt b/app/src/main/java/email/schaal/ocreader/view/NestedScrollWebView.kt index 374fe1ed..cf0c87b2 100644 --- a/app/src/main/java/email/schaal/ocreader/view/NestedScrollWebView.kt +++ b/app/src/main/java/email/schaal/ocreader/view/NestedScrollWebView.kt @@ -1,108 +1,142 @@ +/* + * Copyright (C) 2016 Tobias Rohloff + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package email.schaal.ocreader.view import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet -import android.view.GestureDetector import android.view.MotionEvent import android.webkit.WebView import androidx.core.view.NestedScrollingChild import androidx.core.view.NestedScrollingChildHelper import androidx.core.view.ViewCompat -import kotlin.math.abs - -/** - * Workaround until WebView supports nested scrolling (according to - * http://b.android.com/201385#c3 probably not any time soon) - */ -open class NestedScrollWebView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : WebView(context, attrs, defStyleAttr), NestedScrollingChild { - private val helper = NestedScrollingChildHelper(rootView) - private val gestureDetector = GestureDetector(context, ScrollGestureListener()) - - constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) - constructor(context: Context) : this(context, null) - - private inner class ScrollGestureListener: GestureDetector.SimpleOnGestureListener() { - - override fun onSingleTapUp(e: MotionEvent?): Boolean { - return false - } - - override fun onDown(e: MotionEvent?): Boolean { - startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL) - return true - } - - override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { - dispatchNestedPreScroll(0, distanceY.toInt(), null, null) - - val newDistanceY: Float = if (abs(distanceY) < 10.0f || abs(distanceX) > 10.0f) - 0.0f - else - distanceY - - dispatchNestedScroll(0, newDistanceY.toInt(), 0, 0, null) - - return true - } - - override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { - return true - } - } +import kotlin.math.max +open class NestedScrollWebView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.webViewStyle) : WebView(context, attrs, defStyleAttr), NestedScrollingChild { + private var mLastMotionY = 0 + private val mScrollOffset = IntArray(2) + private val mScrollConsumed = IntArray(2) + private var mNestedYOffset = 0 + private val mChildHelper: NestedScrollingChildHelper = NestedScrollingChildHelper(rootView) init { - ViewCompat.setNestedScrollingEnabled(rootView, true) + isNestedScrollingEnabled = true } @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean { - val handled = gestureDetector.onTouchEvent(event) - if (!handled && event.action == MotionEvent.ACTION_UP) { - stopNestedScroll() + val trackedEvent = MotionEvent.obtain(event) + + if (event.action == MotionEvent.ACTION_DOWN) { + mNestedYOffset = 0 + } + + val y = event.y.toInt() + + event.offsetLocation(0f, mNestedYOffset.toFloat()) + + return when (event.action) { + MotionEvent.ACTION_DOWN -> { + mLastMotionY = y + startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL) + super.onTouchEvent(event) + } + MotionEvent.ACTION_MOVE -> { + var deltaY = mLastMotionY - y + if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) { + deltaY -= mScrollConsumed[1] + trackedEvent.offsetLocation(0f, mScrollOffset[1].toFloat()) + mNestedYOffset += mScrollOffset[1] + } + mLastMotionY = y - mScrollOffset[1] + val oldY = scrollY + val newScrollY = max(0, oldY + deltaY) + val dyConsumed = newScrollY - oldY + val dyUnconsumed = deltaY - dyConsumed + if (dispatchNestedScroll(0, dyConsumed, 0, dyUnconsumed, mScrollOffset)) { + mLastMotionY -= mScrollOffset[1] + trackedEvent.offsetLocation(0f, mScrollOffset[1].toFloat()) + mNestedYOffset += mScrollOffset[1] + } + super.onTouchEvent(trackedEvent).also { + trackedEvent.recycle() + } + } + MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_POINTER_UP, MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { + stopNestedScroll() + super.onTouchEvent(event) + } + else -> false } - return super.onTouchEvent(event) } override fun setNestedScrollingEnabled(enabled: Boolean) { - helper.isNestedScrollingEnabled = enabled + mChildHelper.isNestedScrollingEnabled = enabled } override fun isNestedScrollingEnabled(): Boolean { - return helper.isNestedScrollingEnabled + return mChildHelper.isNestedScrollingEnabled } override fun startNestedScroll(axes: Int): Boolean { - return helper.startNestedScroll(axes) + return mChildHelper.startNestedScroll(axes) } override fun stopNestedScroll() { - helper.stopNestedScroll() + mChildHelper.stopNestedScroll() } override fun hasNestedScrollingParent(): Boolean { - return helper.hasNestedScrollingParent() + return mChildHelper.hasNestedScrollingParent() } - override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?): Boolean { - return helper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow) + override fun dispatchNestedScroll( + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + offsetInWindow: IntArray? + ): Boolean { + return mChildHelper.dispatchNestedScroll( + dxConsumed, + dyConsumed, + dxUnconsumed, + dyUnconsumed, + offsetInWindow + ) } - override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?): Boolean { - return helper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow) + override fun dispatchNestedPreScroll( + dx: Int, + dy: Int, + consumed: IntArray?, + offsetInWindow: IntArray? + ): Boolean { + return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow) } - override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean): Boolean { - return helper.dispatchNestedFling(velocityX, velocityY, consumed) + override fun dispatchNestedFling( + velocityX: Float, + velocityY: Float, + consumed: Boolean + ): Boolean { + return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed) } override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float): Boolean { - return helper.dispatchNestedPreFling(velocityX, velocityY) - } - - override fun onDetachedFromWindow() { - super.onDetachedFromWindow() - helper.onDetachedFromWindow() + return mChildHelper.dispatchNestedPreFling(velocityX, velocityY) } }
\ No newline at end of file diff --git a/app/src/main/res/layout/toolbar_pager.xml b/app/src/main/res/layout/toolbar_pager.xml index ba37b0d6..4b4e92c3 100644 --- a/app/src/main/res/layout/toolbar_pager.xml +++ b/app/src/main/res/layout/toolbar_pager.xml @@ -16,6 +16,7 @@ app:subtitleTextColor="?colorOnPrimarySurface" tools:title="Test Title" tools:subtitle="Test Subtitle" + app:layout_scrollFlags="scroll|enterAlways" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"> </androidx.appcompat.widget.Toolbar> |