diff options
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; + } } } } |