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/Cells/ViewCellRenderer.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/Cells/ViewCellRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs | 120 |
1 files changed, 112 insertions, 8 deletions
diff --git a/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs index 75246220..44f2bbbc 100644 --- a/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs @@ -3,6 +3,8 @@ using Android.Views; using AView = Android.Views.View; using Xamarin.Forms.Internals; using System; +using System.Linq; +using Android.Runtime; namespace Xamarin.Forms.Platform.Android { @@ -53,8 +55,48 @@ namespace Xamarin.Forms.Platform.Android readonly BindableProperty _unevenRows; IVisualElementRenderer _view; ViewCell _viewCell; + GestureDetector _longPressGestureDetector; + ListViewRenderer _listViewRenderer; + bool _watchForLongPress; - public ViewCellContainer(Context context, IVisualElementRenderer view, ViewCell viewCell, View parent, BindableProperty unevenRows, BindableProperty rowHeight) : base(context) + ListViewRenderer ListViewRenderer + { + get + { + if (_listViewRenderer != null) + { + return _listViewRenderer; + } + + var listView = _parent as ListView; + + if (listView == null) + { + return null; + } + + _listViewRenderer = Platform.GetRenderer(listView) as ListViewRenderer; + + return _listViewRenderer; + } + } + + GestureDetector LongPressGestureDetector + { + get + { + if (_longPressGestureDetector != null) + { + return _longPressGestureDetector; + } + + _longPressGestureDetector = new GestureDetector(new LongPressGestureListener(TriggerLongClick)); + return _longPressGestureDetector; + } + } + + public ViewCellContainer(Context context, IVisualElementRenderer view, ViewCell viewCell, View parent, + BindableProperty unevenRows, BindableProperty rowHeight) : base(context) { _view = view; _parent = parent; @@ -63,7 +105,7 @@ namespace Xamarin.Forms.Platform.Android _viewCell = viewCell; AddView(view.View); UpdateIsEnabled(); - UpdateLongClickable(); + UpdateWatchForLongPress(); } protected bool ParentHasUnevenRows @@ -86,6 +128,11 @@ namespace Xamarin.Forms.Platform.Android if (!Enabled) return true; + if (_watchForLongPress) + { + LongPressGestureDetector.OnTouchEvent(ev); + } + return base.OnInterceptTouchEvent(ev); } @@ -137,7 +184,7 @@ namespace Xamarin.Forms.Platform.Android AddView(_view.View); UpdateIsEnabled(); - UpdateLongClickable(); + UpdateWatchForLongPress(); Performance.Stop(); } @@ -182,12 +229,69 @@ namespace Xamarin.Forms.Platform.Android Performance.Stop(); } - void UpdateLongClickable() + void UpdateWatchForLongPress() { - // In order for context menu long presses/clicks to work on ViewCells which have - // and Clickable content, we have to make the container view LongClickable - // If we don't have a context menu, we don't have to worry about it - _view.View.LongClickable = _viewCell.ContextActions.Count > 0; + var vw = _view.Element as Xamarin.Forms.View; + if (vw == null) + { + return; + } + + // If the view cell has any context actions and the View itself has any Tap Gestures, they're going + // to conflict with one another - the Tap Gesture handling will prevent the ListViewAdapter's + // LongClick handling from happening. So we need to watch locally for LongPress and if we see it, + // trigger the LongClick manually. + _watchForLongPress = _viewCell.ContextActions.Count > 0 + && vw.GestureRecognizers.Any(t => t is TapGestureRecognizer); + } + + void TriggerLongClick() + { + ListViewRenderer?.LongClickOn(this); + } + + internal class LongPressGestureListener : Java.Lang.Object, GestureDetector.IOnGestureListener + { + readonly Action _onLongClick; + + internal LongPressGestureListener(Action onLongClick) + { + _onLongClick = onLongClick; + } + + internal LongPressGestureListener(IntPtr handle, JniHandleOwnership ownership) : base(handle, ownership) + { + } + + public bool OnDown(MotionEvent e) + { + return true; + } + + public bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) + { + return false; + } + + public void OnLongPress(MotionEvent e) + { + _onLongClick(); + } + + public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) + { + return false; + } + + public void OnShowPress(MotionEvent e) + { + + } + + public bool OnSingleTapUp(MotionEvent e) + { + return false; + } } } } |