From 75d0ce08d220439f3cedb9872ab1fda40dbeb35d Mon Sep 17 00:00:00 2001 From: Andrei Misiukevich Date: Sat, 21 Jul 2018 12:08:35 +0300 Subject: [PATCH] sample updates --- .../ContextMenuScrollViewRenderer.cs | 39 +++++++--- ContextMenu/ContextMenu.csproj | 3 + ContextMenu/ContextMenuScrollView.cs | 71 +++++++++---------- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/ContextMenu.Droid/ContextMenuScrollViewRenderer.cs b/ContextMenu.Droid/ContextMenuScrollViewRenderer.cs index 19d8249..96952da 100644 --- a/ContextMenu.Droid/ContextMenuScrollViewRenderer.cs +++ b/ContextMenu.Droid/ContextMenuScrollViewRenderer.cs @@ -18,30 +18,43 @@ namespace ContextMenu.Droid [Preserve(AllMembers = true)] public class ContextMenuScrollViewRenderer : ScrollViewRenderer { - private readonly GestureDetector _detector; + private GestureDetector _detector; private bool _isAttachedNew; [Obsolete("For Forms <= 2.4")] public ContextMenuScrollViewRenderer() { + CreateGestureDetector(); } public ContextMenuScrollViewRenderer(Context context) : base(context) { - var listener = new GalleyGestureListener(); - _detector = new GestureDetector(listener); - listener.Flinged += OnFlinged; + CreateGestureDetector(); } public override bool OnTouchEvent(MotionEvent ev) { - _detector.OnTouchEvent(ev); + try + { + _detector.OnTouchEvent(ev); + } + catch(ObjectDisposedException) + { + CreateGestureDetector(); + } return base.OnTouchEvent(ev); } public override bool OnGenericMotionEvent(MotionEvent e) { - _detector.OnGenericMotionEvent(e); + try + { + _detector.OnGenericMotionEvent(e); + } + catch (ObjectDisposedException) + { + CreateGestureDetector(); + } return base.OnGenericMotionEvent(e); } @@ -151,7 +164,7 @@ private async void OnScrollToRequestedNew(object sender, ScrollToRequestedEventA switch ((Element as XScrollView).Orientation) { case ScrollOrientation.Horizontal: - if(animated) + if (animated) { Device.BeginInvokeOnMainThread(() => hScrolView.SmoothScrollTo(x, y)); break; @@ -172,7 +185,8 @@ private async void OnScrollToRequestedNew(object sender, ScrollToRequestedEventA if (animated) { - Device.BeginInvokeOnMainThread(() => { + Device.BeginInvokeOnMainThread(() => + { hScrolView.SmoothScrollTo(x, y); SmoothScrollTo(x, y); }); @@ -186,10 +200,17 @@ private async void OnScrollToRequestedNew(object sender, ScrollToRequestedEventA Controller.SendScrollFinished(); } + private void CreateGestureDetector() + { + var listener = new ContextGestureListener(); + _detector = new GestureDetector(listener); + listener.Flinged += OnFlinged; + } + #endregion } - internal class GalleyGestureListener : GestureDetector.SimpleOnGestureListener + internal class ContextGestureListener : GestureDetector.SimpleOnGestureListener { internal event Action Flinged; diff --git a/ContextMenu/ContextMenu.csproj b/ContextMenu/ContextMenu.csproj index f593d94..0e753ce 100644 --- a/ContextMenu/ContextMenu.csproj +++ b/ContextMenu/ContextMenu.csproj @@ -10,4 +10,7 @@ + + + diff --git a/ContextMenu/ContextMenuScrollView.cs b/ContextMenu/ContextMenuScrollView.cs index 6874c3d..06cec56 100644 --- a/ContextMenu/ContextMenuScrollView.cs +++ b/ContextMenu/ContextMenuScrollView.cs @@ -5,8 +5,8 @@ namespace ContextMenu { - public enum GalleyScrollDirection { Close, Open } - public enum GalleyScrollState { Closed, Opened, Moving } + public enum ScrollDirection { Close, Open } + public enum ScrollState { Closed, Opened, Moving } public class ContextMenuScrollView : ScrollView { @@ -16,16 +16,6 @@ public class ContextMenuScrollView : ScrollView private View _contentView; private View _contextView = new ContentView { WidthRequest = 1 }; - public StackLayout ViewStack { get; } - public GalleyScrollDirection CurrentDirection { get; private set; } - public GalleyScrollState CurrentState { get; private set; } - public bool HasBeenAccelerated { get; private set; } - public double PrevScrollX { get; private set; } - public bool IsInteracted { get; private set; } - - public bool IsOpenDirection => CurrentDirection == GalleyScrollDirection.Open; - public bool IsDirectionAndStateSame => (int)CurrentDirection == (int)CurrentState; - public ContextMenuScrollView() { Orientation = ScrollOrientation.Horizontal; @@ -46,6 +36,15 @@ public ContextMenuScrollView() Scrolled += OnScrolled; } + protected StackLayout ViewStack { get; } + protected ScrollDirection CurrentDirection { get; private set; } + protected ScrollState CurrentState { get; private set; } + protected bool HasBeenAccelerated { get; private set; } + protected double PrevScrollX { get; private set; } + protected bool IsInteracted { get; private set; } + protected bool IsOpenDirection => CurrentDirection == ScrollDirection.Open; + protected bool IsDirectionAndStateSame => (int)CurrentDirection == (int)CurrentState; + public View ContentView { get => _contentView; @@ -83,8 +82,6 @@ public View ContextView } } - public bool IsClosed => CurrentState == GalleyScrollState.Closed; - public async void ForceCloseContextMenu(ContextMenuScrollView view, bool animated) { if (view == null) @@ -96,12 +93,12 @@ public async void ForceCloseContextMenu(ContextMenuScrollView view, bool animate { if (view.ScrollX > 0) { - await view.ScrollToAsync(0, 0, animated);; + await view.ScrollToAsync(0, 0, animated); } } catch (Exception ex) { - Debug.WriteLine(ex); + Console.WriteLine(ex); } } @@ -126,7 +123,7 @@ public virtual async void OnTouchEnded() return; } - var width = GetContextViewWidth(); + var width = ContextView.Width; var isOpen = IsOpenDirection ? ScrollX > GetMovingWidth(width) : ScrollX > width - GetMovingWidth(width); @@ -139,7 +136,7 @@ public virtual async Task OnFlingStarted(bool needScroll = true, bool animated = if (needScroll) { - var task = ScrollToAsync(IsOpenDirection ? GetContextViewWidth() : 0, 0, animated); + var task = ScrollToAsync(IsOpenDirection ? ContextView.Width : 0, 0, animated); if (inMainThread) { var completionSource = new TaskCompletionSource(); @@ -158,8 +155,8 @@ public virtual async Task OnFlingStarted(bool needScroll = true, bool animated = public async Task MoveSideMenu(bool isOpen = false, bool animated = true) { CurrentDirection = isOpen - ? GalleyScrollDirection.Open - : GalleyScrollDirection.Close; + ? ScrollDirection.Open + : ScrollDirection.Close; await OnFlingStarted(!IsDirectionAndStateSame, animated, true); } @@ -174,39 +171,37 @@ protected virtual void OnScrolled(object sender, ScrolledEventArgs args) CurrentDirection = Math.Abs(PrevScrollX - ScrollX) < double.Epsilon ? CurrentDirection : PrevScrollX > ScrollX - ? GalleyScrollDirection.Close - : GalleyScrollDirection.Open; + ? ScrollDirection.Close + : ScrollDirection.Open; PrevScrollX = ScrollX; CheckScrollState(); CheckActionBarOpened(); } - protected virtual void CheckScrollState() + protected virtual double GetMovingWidth(double contextWidth) + => contextWidth * 0.33; + + protected void CheckScrollState() { if (Math.Abs(ScrollX) <= double.Epsilon) { - CurrentState = GalleyScrollState.Closed; - } - else if (Math.Abs(ScrollX - GetContextViewWidth()) <= double.Epsilon) - { - CurrentState = GalleyScrollState.Opened; + CurrentState = ScrollState.Closed; + return; } - else + + if (Math.Abs(ScrollX - ContextView.Width) <= double.Epsilon) { - CurrentState = GalleyScrollState.Moving; + CurrentState = ScrollState.Opened; + return; } - } - protected virtual double GetContextViewWidth() - => ContextView.Width; - - protected virtual double GetMovingWidth(double contextWidth) - => contextWidth * 0.3; + CurrentState = ScrollState.Moving; + } protected bool CheckIsOpen() { - var width = GetContextViewWidth(); + var width = ContextView.Width; return IsOpenDirection ? ScrollX > GetMovingWidth(width) : ScrollX > width - GetMovingWidth(width); @@ -214,7 +209,7 @@ protected bool CheckIsOpen() protected void CheckActionBarOpened() { - if(ScrollX >= GetContextViewWidth() && !IsInteracted) + if(ScrollX >= ContextView.Width && !IsInteracted) { ActionBarOpened?.Invoke(); }