Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for swiping to dismiss and cancelling by moving to the sides #6

Merged
merged 4 commits into from
Mar 16, 2021
Merged
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 @@ -4,10 +4,7 @@ import android.content.Context
import android.graphics.Rect
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.*
import android.widget.Toast
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.gallery_item.*
Expand Down Expand Up @@ -60,7 +57,7 @@ class GalleryImageFragment : Fragment(), SingleTapHandler.OnSingleTapListener {
.enableDoubleTapToZoom()
.enablePinchToZoom()
.enableSingleTap(object : SingleTapHandler.OnSingleTapListener {
override fun onSingleTap() {
override fun onSingleTap(event: MotionEvent) {
Toast.makeText(image_view.context, picture.name, Toast.LENGTH_SHORT).show()
}
})
Expand All @@ -86,8 +83,8 @@ class GalleryImageFragment : Fragment(), SingleTapHandler.OnSingleTapListener {
return Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels).height()
}

override fun onSingleTap() {
tapListener?.onSingleTap()
override fun onSingleTap(event: MotionEvent) {
tapListener?.onSingleTap(event)
}

companion object {
Expand Down
52 changes: 41 additions & 11 deletions library/src/main/java/nl/nos/imagin/ScrollHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.ImageView
import kotlin.math.abs

/**
* Allow the user to move the image of the image view when zoomed in.
Expand Down Expand Up @@ -37,9 +38,7 @@ class ScrollHandler(
distanceX: Float,
distanceY: Float
): Boolean {
if (imageView.rightEdgeIsVisible() && distanceX > 0 && moveMotionEvent?.pointerCount == 1) {
imageView.parent?.requestDisallowInterceptTouchEvent(false)
} else if (imageView.leftEdgeIsVisible() && distanceX < 0 && moveMotionEvent?.pointerCount == 1) {
if (shouldAllowIntercept(firstMotionEvent, moveMotionEvent, distanceX)){
imageView.parent?.requestDisallowInterceptTouchEvent(false)
}

Expand All @@ -65,10 +64,37 @@ class ScrollHandler(
)
}

return super.onScroll(firstMotionEvent, moveMotionEvent, distanceX, distanceY)
return true
}
})

/**
* Return whether the parent should be able to intercept touch events.
*/
private fun shouldAllowIntercept(
firstMotionEvent: MotionEvent?,
moveMotionEvent: MotionEvent?,
distanceX: Float
): Boolean {
if (isScrollingVertically(firstMotionEvent, moveMotionEvent)) return false
if (moveMotionEvent?.pointerCount != 1) return false

if (imageView.rightEdgeIsVisible() && distanceX > 0) return true
if (imageView.leftEdgeIsVisible() && distanceX < 0) return true

return false
}

private fun isScrollingVertically(
firstMotionEvent: MotionEvent?,
moveMotionEvent: MotionEvent?
): Boolean {
if (firstMotionEvent == null) return false
if (moveMotionEvent == null) return false

return abs(firstMotionEvent.y - moveMotionEvent.y) > abs(firstMotionEvent.x - moveMotionEvent.x)
}

private fun ImageView.leftEdgeIsVisible(): Boolean {
val maxTranslationXScale = (scaleX * width - width) / 2
return translationX >= maxTranslationXScale
Expand All @@ -94,7 +120,8 @@ class ScrollHandler(
imageView.translationX,
imageView.scaleX,
imageView.width,
imageSize.first
imageSize.first,
event
)) {
outOfBoundScrolledListener?.invoke()
return consumed
Expand All @@ -104,7 +131,8 @@ class ScrollHandler(
imageView.translationY,
imageView.scaleY,
imageView.height,
imageSize.second
imageSize.second,
event
)) {
outOfBoundScrolledListener?.invoke()
return consumed
Expand Down Expand Up @@ -165,12 +193,14 @@ class ScrollHandler(
* Whether the listener should be triggered or not.
*/
private fun shouldTriggerOutOfBoundListener(
distanceToClose: Int,
imageViewTranslation: Float,
imageViewScale: Float,
imageViewSize: Int,
imageSize: Int
distanceToClose: Int,
imageViewTranslation: Float,
imageViewScale: Float,
imageViewSize: Int,
imageSize: Int,
action: MotionEvent
): Boolean {
if (action.action == MotionEvent.ACTION_CANCEL) return false
if (imageViewScale > 1f) return false

val maxTranslation =
Expand Down