diff --git a/README.md b/README.md
index 0b22325..9539137 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,10 @@ A container for view hierarchies that can be panned or zoomed.
app:verticalPanEnabled="true"
app:zoomEnabled="true"
app:flingEnabled="true"
+ app:scrollEnabled="true"
+ app:oneFingerScrollEnabled="true"
+ app:twoFingersScrollEnabled="true"
+ app:threeFingersScrollEnabled="true"
app:minZoom="0.7"
app:minZoomType="zoom"
app:maxZoom="2.5"
@@ -106,6 +110,10 @@ An `ImageView` implementation to control pan and zoom over its Drawable or Bitma
app:verticalPanEnabled="true"
app:zoomEnabled="true"
app:flingEnabled="true"
+ app:scrollEnabled="true"
+ app:oneFingerScrollEnabled="true"
+ app:twoFingersScrollEnabled="true"
+ app:threeFingersScrollEnabled="true"
app:minZoom="0.7"
app:minZoomType="zoom"
app:maxZoom="2.5"
@@ -158,6 +166,10 @@ that streams image buffers into a `Surface`.
app:verticalPanEnabled="true"
app:zoomEnabled="true"
app:flingEnabled="true"
+ app:scrollEnabled="true"
+ app:oneFingerScrollEnabled="true"
+ app:twoFingersScrollEnabled="true"
+ app:threeFingersScrollEnabled="true"
app:minZoom="1"
app:minZoomType="zoom"
app:maxZoom="2.5"
@@ -351,6 +363,10 @@ In any case the current scale is not considered, so your system won't change if
|`setHorizontalPanEnabled(boolean)`|If true, the content will be allowed to pan **horizontally** by user input.|`true`|
|`setVerticalPanEnabled(boolean)`|If true, the content will be allowed to pan **vertically** by user input.|`true`|
|`setFlingEnabled(boolean)`|If true, fling gestures will be detected.|`true`|
+|`setScrollEnabled(boolean)`|If true, scroll gestures will be detected.|`true`|
+|`setOneFingerScrollEnabled(boolean)`|If true, one finger scroll gestures will be detected.|`true`|
+|`setTwoFingersScrollEnabled(boolean)`|If true, two fingers scroll gestures will be detected.|`true`|
+|`setThreeFingersScrollEnabled(boolean)`|If true, three fingers scroll gestures will be detected.|`true`|
|`setAllowFlingInOverscroll(boolean)`|If true, fling gestures will be allowed even when detected while overscrolled. This might cause artifacts so it is disabled by default.|`false`|
|`panTo(float, float, boolean)`|Pans to the given values, animating if needed.|`-`|
|`panBy(float, float, boolean)`|Applies the given deltas to the current pan, animating if needed.|`-`|
diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt
index 8c102f9..7148d48 100644
--- a/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt
@@ -229,6 +229,34 @@ interface ZoomApi {
fun setFlingEnabled(enabled: Boolean)
// TODO (v2) rename to var isFlingEnabled or isGestureFlingEnabled to clearly differentiate gestures and engine movements (pan/zoom)
+ /**
+ * Controls whether scroll gesture is enabled or not.
+ *
+ * @param enabled true enables scroll gesture, false disables it
+ */
+ fun setScrollEnabled(enabled: Boolean)
+
+ /**
+ * Controls whether one finger scroll gesture is enabled or not.
+ *
+ * @param enabled true enables one finger scroll gesture, false disables it
+ */
+ fun setOneFingerScrollEnabled(enabled: Boolean)
+
+ /**
+ * Controls whether two fingers scroll gesture is enabled or not.
+ *
+ * @param enabled true enables two fingers scroll gesture, false disables it
+ */
+ fun setTwoFingersScrollEnabled(enabled: Boolean)
+
+ /**
+ * Controls whether three fingers scroll gesture is enabled or not.
+ *
+ * @param enabled true enables three fingers scroll gesture, false disables it
+ */
+ fun setThreeFingersScrollEnabled(enabled: Boolean)
+
/**
* Controls whether fling events are allowed when the view is in an overscrolled state.
*
diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt
index 3d03f3b..b5fc5de 100644
--- a/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt
@@ -430,6 +430,42 @@ internal constructor(context: Context) : ZoomApi {
scrollFlingDetector.flingEnabled = enabled
}
+ /**
+ * Controls whether scroll gesture is enabled or not.
+ *
+ * @param enabled true enables scroll gesture, false disables it
+ */
+ override fun setScrollEnabled(enabled: Boolean) {
+ scrollFlingDetector.scrollEnabled = enabled
+ }
+
+ /**
+ * Controls whether one finger scroll gesture is enabled or not.
+ *
+ * @param enabled true enables one finger scroll gesture, false disables it
+ */
+ override fun setOneFingerScrollEnabled(enabled: Boolean) {
+ scrollFlingDetector.oneFingerScrollEnabled = enabled
+ }
+
+ /**
+ * Controls whether two fingers scroll gesture is enabled or not.
+ *
+ * @param enabled true enables two fingers scroll gesture, false disables it
+ */
+ override fun setTwoFingersScrollEnabled(enabled: Boolean) {
+ scrollFlingDetector.twoFingersScrollEnabled = enabled
+ }
+
+ /**
+ * Controls whether three fingers scroll gesture is enabled or not.
+ *
+ * @param enabled true enables three fingers scroll gesture, false disables it
+ */
+ override fun setThreeFingersScrollEnabled(enabled: Boolean) {
+ scrollFlingDetector.threeFingersScrollEnabled = enabled
+ }
+
/**
* Controls whether fling events are allowed when the view is in an overscrolled state.
*
diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt
index 74f2d8a..9a26156 100644
--- a/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt
@@ -42,6 +42,10 @@ open class ZoomImageView private constructor(
val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, true)
val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true)
val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true)
+ val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true)
+ val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true)
+ val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true)
+ val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true)
val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true)
val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, ZoomApi.MIN_ZOOM_DEFAULT)
val maxZoom = a.getFloat(R.styleable.ZoomEngine_maxZoom, ZoomApi.MAX_ZOOM_DEFAULT)
@@ -72,6 +76,10 @@ open class ZoomImageView private constructor(
setOverPinchable(overPinchable)
setZoomEnabled(zoomEnabled)
setFlingEnabled(flingEnabled)
+ setScrollEnabled(scrollEnabled)
+ setOneFingerScrollEnabled(oneFingerScrollEnabled)
+ setTwoFingersScrollEnabled(twoFingersScrollEnabled)
+ setThreeFingersScrollEnabled(threeFingersScrollEnabled)
setAllowFlingInOverscroll(allowFlingInOverscroll)
setAnimationDuration(animationDuration)
setMinZoom(minZoom, minZoomMode)
diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt
index b3dae23..acb56c2 100644
--- a/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt
@@ -47,6 +47,10 @@ open class ZoomLayout private constructor(
val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, true)
val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true)
val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true)
+ val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true)
+ val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true)
+ val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true)
+ val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true)
val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true)
val hasChildren = a.getBoolean(R.styleable.ZoomEngine_hasClickableChildren, false)
val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, ZoomApi.MIN_ZOOM_DEFAULT)
@@ -73,6 +77,10 @@ open class ZoomLayout private constructor(
setOverPinchable(overPinchable)
setZoomEnabled(zoomEnabled)
setFlingEnabled(flingEnabled)
+ setScrollEnabled(scrollEnabled)
+ setOneFingerScrollEnabled(oneFingerScrollEnabled)
+ setTwoFingersScrollEnabled(twoFingersScrollEnabled)
+ setThreeFingersScrollEnabled(threeFingersScrollEnabled)
setAllowFlingInOverscroll(allowFlingInOverscroll)
setAnimationDuration(animationDuration)
setMinZoom(minZoom, minZoomMode)
diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt
index 8b5883f..a399534 100644
--- a/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt
@@ -152,6 +152,10 @@ open class ZoomSurfaceView private constructor(
val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, false)
val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true)
val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true)
+ val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true)
+ val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true)
+ val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true)
+ val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true)
val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true)
val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, 1F)
val maxZoom = a.getFloat(R.styleable.ZoomEngine_maxZoom, ZoomApi.MAX_ZOOM_DEFAULT)
@@ -180,6 +184,10 @@ open class ZoomSurfaceView private constructor(
setOverPinchable(overPinchable)
setZoomEnabled(zoomEnabled)
setFlingEnabled(flingEnabled)
+ setScrollEnabled(scrollEnabled)
+ setOneFingerScrollEnabled(oneFingerScrollEnabled)
+ setTwoFingersScrollEnabled(twoFingersScrollEnabled)
+ setThreeFingersScrollEnabled(threeFingersScrollEnabled)
setAllowFlingInOverscroll(allowFlingInOverscroll)
setAnimationDuration(animationDuration)
setMinZoom(minZoom, minZoomMode)
diff --git a/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt b/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt
index b841ccb..ea72e14 100644
--- a/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt
+++ b/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt
@@ -37,6 +37,10 @@ internal class ScrollFlingDetector(
private val panStatusY = PanManager.Status()
internal var flingEnabled = true
+ internal var scrollEnabled = true
+ internal var oneFingerScrollEnabled = true
+ internal var twoFingersScrollEnabled = true
+ internal var threeFingersScrollEnabled = true
internal var flingInOverPanEnabled = false
/**
@@ -144,6 +148,15 @@ internal class ScrollFlingDetector(
@ZoomApi.ScaledPan distanceX: Float,
@ZoomApi.ScaledPan distanceY: Float
): Boolean {
+ if (!scrollEnabled) return false
+
+ val isOneFinger = e2?.pointerCount == 1
+ val isTwoFingers = e2?.pointerCount == 2
+ val isThreeFingers = e2?.pointerCount == 3
+
+ if (!oneFingerScrollEnabled && isOneFinger) return false
+ if (!twoFingersScrollEnabled && isTwoFingers) return false
+ if (!threeFingersScrollEnabled && isThreeFingers) return false
if (!panManager.isEnabled) return false
if (!stateController.setScrolling()) return false
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
index b9fbb4a..30035b7 100644
--- a/library/src/main/res/values/attrs.xml
+++ b/library/src/main/res/values/attrs.xml
@@ -9,6 +9,10 @@
+
+
+
+