diff options
author | E.Z. Hart <hartez@users.noreply.github.com> | 2017-09-15 12:49:19 -0600 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2017-09-15 20:28:38 +0100 |
commit | fc3ad54edbe4f7e33e2d8c4f9bc217b93dd62ecc (patch) | |
tree | e63d0d922f62198993735c34811ede1a0d69f1b8 /Xamarin.Forms.Platform.Android/InnerGestureListener.cs | |
parent | d1bf93be200b3d3c48d0d292bf455f444485d8f9 (diff) | |
download | xamarin-forms-fc3ad54edbe4f7e33e2d8c4f9bc217b93dd62ecc.tar.gz xamarin-forms-fc3ad54edbe4f7e33e2d8c4f9bc217b93dd62ecc.tar.bz2 xamarin-forms-fc3ad54edbe4f7e33e2d8c4f9bc217b93dd62ecc.zip |
[Android] Restore pinch gestures and fix listview item selection (#1135)
* Repro
* Fail test if tap command is executed more than once.
* Update error message
* Handle context actions and taps without breaking selection
* Fix 58833 test
* Prevent InnerGestureListener from swallowing clicks and preventing selection
* Repro for 57515
* Add gestures category to appropriate tests
* Test notes
* Restore the tap gesture handling
* Better test name
* Simplify InnerGestureListener constructor; handle OnDown only if listening
* OnInterceptTouchEvent for IsEnabled handling
* Fix incorrect class filter in TapGestureHandler
* Restore MotionEventHelper
* Add IsEnabled check on OnTouchEvent
* Reinstate pinch gestures
* Checkpoint (trying to figure out how to handle button elevation)
* Rip out elevation ordering in DefaultRenderer
* Working version of pinch-to-zoom test
* Clean up lazy initializers, remove unnecessary members
* One fewer Java.Lang.Object
* Fix issue number; clean up notes and issue number changes
* Remove conditional
* Restore correct issue number
* Automate all the options for 58833 test
* Remove unnecessary automation ID
* Formatting cleanup; reinstate gesture detector dispose checks
* Updating Xamarin UI test version to avoid iOS crashes; update test to open iOS context actions
* Attempting to get 58833 test running on all iOS versions
Diffstat (limited to 'Xamarin.Forms.Platform.Android/InnerGestureListener.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Android/InnerGestureListener.cs | 98 |
1 files changed, 58 insertions, 40 deletions
diff --git a/Xamarin.Forms.Platform.Android/InnerGestureListener.cs b/Xamarin.Forms.Platform.Android/InnerGestureListener.cs index 928c9c13..99c1d63d 100644 --- a/Xamarin.Forms.Platform.Android/InnerGestureListener.cs +++ b/Xamarin.Forms.Platform.Android/InnerGestureListener.cs @@ -9,6 +9,8 @@ namespace Xamarin.Forms.Platform.Android { internal class InnerGestureListener : Object, GestureDetector.IOnGestureListener, GestureDetector.IOnDoubleTapListener { + readonly TapGestureHandler _tapGestureHandler; + readonly PanGestureHandler _panGestureHandler; bool _isScrolling; float _lastX; float _lastY; @@ -20,25 +22,31 @@ namespace Xamarin.Forms.Platform.Android Func<int, bool> _tapDelegate; Func<int, IEnumerable<TapGestureRecognizer>> _tapGestureRecognizers; - public InnerGestureListener(Func<int, bool> tapDelegate, Func<int, IEnumerable<TapGestureRecognizer>> tapGestureRecognizers, Func<float, float, int, bool> scrollDelegate, - Func<int, bool> scrollStartedDelegate, Func<bool> scrollCompleteDelegate) + public InnerGestureListener(TapGestureHandler tapGestureHandler, PanGestureHandler panGestureHandler) { - if (tapDelegate == null) - throw new ArgumentNullException(nameof(tapDelegate)); - if (tapGestureRecognizers == null) - throw new ArgumentNullException(nameof(tapGestureRecognizers)); - if (scrollDelegate == null) - throw new ArgumentNullException(nameof(scrollDelegate)); - if (scrollStartedDelegate == null) - throw new ArgumentNullException(nameof(scrollStartedDelegate)); - if (scrollCompleteDelegate == null) - throw new ArgumentNullException(nameof(scrollCompleteDelegate)); + if (tapGestureHandler == null) + { + throw new ArgumentNullException(nameof(tapGestureHandler)); + } + + if (panGestureHandler == null) + { + throw new ArgumentNullException(nameof(panGestureHandler)); + } + + _tapGestureHandler = tapGestureHandler; + _panGestureHandler = panGestureHandler; - _tapDelegate = tapDelegate; - _tapGestureRecognizers = tapGestureRecognizers; - _scrollDelegate = scrollDelegate; - _scrollStartedDelegate = scrollStartedDelegate; - _scrollCompleteDelegate = scrollCompleteDelegate; + _tapDelegate = tapGestureHandler.OnTap; + _tapGestureRecognizers = tapGestureHandler.TapGestureRecognizers; + _scrollDelegate = panGestureHandler.OnPan; + _scrollStartedDelegate = panGestureHandler.OnPanStarted; + _scrollCompleteDelegate = panGestureHandler.OnPanComplete; + } + + bool HasAnyGestures() + { + return _panGestureHandler.HasAnyGestures() || _tapGestureHandler.HasAnyGestures(); } // This is needed because GestureRecognizer callbacks can be delayed several hundred milliseconds @@ -48,16 +56,6 @@ namespace Xamarin.Forms.Platform.Android { } - internal void OnTouchEvent(MotionEvent e) - { - if (e.Action == MotionEventActions.Up) - EndScrolling(); - else if (e.Action == MotionEventActions.Down) - SetStartingPosition(e); - else if (e.Action == MotionEventActions.Move) - StartScrolling(e); - } - bool GestureDetector.IOnDoubleTapListener.OnDoubleTap(MotionEvent e) { if (_disposed) @@ -71,21 +69,19 @@ namespace Xamarin.Forms.Platform.Android return false; } - bool GestureDetector.IOnDoubleTapListener.OnSingleTapConfirmed(MotionEvent e) - { - if (_disposed) - return false; - - // optimization: only wait for a second tap if there is a double tap handler - if (!HasDoubleTapHandler()) - return false; - - return _tapDelegate(1); - } - bool GestureDetector.IOnGestureListener.OnDown(MotionEvent e) { SetStartingPosition(e); + + if (HasAnyGestures()) + { + // If we have any gestures to listen for, we need to return true to show we're interested in the rest + // of the events. + return true; + } + + // Since we don't have any gestures we're listening for, we return false to show we're not interested + // and let parent controls have a whack at the events return false; } @@ -119,10 +115,32 @@ namespace Xamarin.Forms.Platform.Android if (_disposed) return false; - // optimization: do not wait for a second tap if there is no double tap handler if (HasDoubleTapHandler()) + { + // Because we have a handler for double-tap, we need to wait for + // OnSingleTapConfirmed (to verify it's really just a single tap) before running the delegate return false; + } + + // A single tap has occurred and there's no handler for double tap to worry about, + // so we can go ahead and run the delegate + return _tapDelegate(1); + } + + bool GestureDetector.IOnDoubleTapListener.OnSingleTapConfirmed(MotionEvent e) + { + if (_disposed) + return false; + + if (!HasDoubleTapHandler()) + { + // We're not worried about double-tap, so OnSingleTap has already run the delegate + // there's nothing for us to do here + return false; + } + // Since there was a double-tap handler, we had to wait for OnSingleTapConfirmed; + // Now that we're sure it's a single tap, we can run the delegate return _tapDelegate(1); } |