From 23614ca8c6cc78cb2b1df91977fd539a9fa159df Mon Sep 17 00:00:00 2001 From: Paul DiPietro Date: Wed, 3 Aug 2016 03:50:31 -0500 Subject: [PATCH] [Android] Fix ListView contextual actions not closing in AppCompat's NavigationPage/TabbedPage (#272) * [Android] Fix ListView contextual actions not closing upon navigation in AppCompat The Platform type in the ListViewAdapter was being treated as the non-AppCompat type, and the NavAnimationInProgress value was not being set as necessary in the NavigationPageRenderer. * [Android] Add fix for TabbedPage swipes not closing contextual actions Similar fix where swiping to another tab with the context menu open would not close it. Relies on the prior commit. --- .../Bugzilla40824.cs | 57 ++++++++++++++++++++ .../Bugzilla42364.cs | 63 ++++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 2 + .../AppCompat/NavigationPageRenderer.cs | 6 ++- .../AppCompat/TabbedPageRenderer.cs | 2 + .../Renderers/ListViewAdapter.cs | 14 ++++- 6 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40824.cs create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42364.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40824.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40824.cs new file mode 100644 index 0000000..09b853e --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40824.cs @@ -0,0 +1,57 @@ +using System; + +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using System.Collections.Generic; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 40824, "ListView item's contextual action menu not being closed upon navigation in AppCompat")] + public class Bugzilla40824 : TestContentPage + { + protected override void Init() + { + var list = new ListView + { + ItemsSource = new List + { + "Cat", + "Dog", + "Rat" + }, + ItemTemplate = new DataTemplate(() => + { + var cell = new TextCell(); + cell.SetBinding(TextCell.TextProperty, "."); + cell.ContextActions.Add(new MenuItem + { + Text = "Action", + Icon = "icon", + IsDestructive = true, + Command = new Command(() => DisplayAlert("TITLE", "Context action invoked", "Ok")), + }); + return cell; + }), + }; + + Content = new StackLayout + { + Children = + { + new Button + { + Text = "Go to next page", + Command = new Command(() => Navigation.PushAsync(new ContentPage { Title = "Next Page", Content = new Label { Text = "Here" } })) + }, + list + } + }; + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42364.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42364.cs new file mode 100644 index 0000000..2d85e31 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla42364.cs @@ -0,0 +1,63 @@ +using System; + +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using System.Collections.Generic; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 42364, "ListView item's contextual action menu not being closed upon swiping a TabbedPage in AppCompat")] + public class Bugzilla42354 : TestTabbedPage + { + protected override void Init() + { + var list = new ListView + { + ItemsSource = new List + { + "Cat", + "Dog", + "Rat" + }, + ItemTemplate = new DataTemplate(() => + { + var cell = new TextCell(); + cell.SetBinding(TextCell.TextProperty, "."); + cell.ContextActions.Add(new MenuItem + { + Text = "Action", + Icon = "icon", + IsDestructive = true, + Command = new Command(() => DisplayAlert("TITLE", "Context action invoked", "Ok")), + }); + return cell; + }), + }; + + Children.Add(new ContentPage + { + Title = "Page One", + Content = new StackLayout + { + Children = + { + new Button + { + Text = "Go to next page", + Command = new Command(() => Navigation.PushAsync(new ContentPage { Title = "Next Page", Content = new Label { Text = "Here" } })) + }, + list + } + } + }); + + Children.Add(new ContentPage { Title = "Page Two" }); + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 67bfb32..f9aeff6 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -105,6 +105,7 @@ + @@ -118,6 +119,7 @@ + diff --git a/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs index 2bc182d..f591f05 100644 --- a/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs +++ b/Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs @@ -573,6 +573,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat Current = view; + ((Platform)Element.Platform).NavAnimationInProgress = true; FragmentTransaction transaction = fm.BeginTransaction(); if (animated) @@ -606,6 +607,8 @@ namespace Xamarin.Forms.Platform.Android.AppCompat transaction.Show(toShow); else transaction.Add(Id, toShow); + + ((Platform)Element.Platform).NavAnimationInProgress = false; } else { @@ -614,13 +617,14 @@ namespace Xamarin.Forms.Platform.Android.AppCompat transaction.Hide(currentToHide); transaction.Add(Id, fragment); fragments.Add(fragment); + ((Platform)Element.Platform).NavAnimationInProgress = false; } } transaction.Commit(); // The fragment transitions don't really SUPPORT telling you when they end // There are some hacks you can do, but they actually are worse than just doing this: - + if (animated) { if (!removed) diff --git a/Xamarin.Forms.Platform.Android/AppCompat/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/TabbedPageRenderer.cs index 243e5c1..3c952a9 100644 --- a/Xamarin.Forms.Platform.Android/AppCompat/TabbedPageRenderer.cs +++ b/Xamarin.Forms.Platform.Android/AppCompat/TabbedPageRenderer.cs @@ -264,7 +264,9 @@ namespace Xamarin.Forms.Platform.Android.AppCompat void ScrollToCurrentPage() { + ((Platform)Element.Platform).NavAnimationInProgress = true; _viewPager.SetCurrentItem(Element.Children.IndexOf(Element.CurrentPage), UseAnimations); + ((Platform)Element.Platform).NavAnimationInProgress = false; } void UpdateIgnoreContainerAreas() diff --git a/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs b/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs index 5dedef6..a38aea0 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs @@ -52,7 +52,11 @@ namespace Xamarin.Forms.Platform.Android realListView.OnItemClickListener = this; realListView.OnItemLongClickListener = this; - MessagingCenter.Subscribe(this, Platform.CloseContextActionsSignalName, p => CloseContextAction()); + var platform = _listView.Platform; + if (platform.GetType() == typeof(AppCompat.Platform)) + MessagingCenter.Subscribe(this, AppCompat.Platform.CloseContextActionsSignalName, p => CloseContextAction()); + else + MessagingCenter.Subscribe(this, Platform.CloseContextActionsSignalName, p => CloseContextAction()); } public override int Count @@ -325,7 +329,13 @@ namespace Xamarin.Forms.Platform.Android if (disposing) { CloseContextAction(); - MessagingCenter.Unsubscribe(this, Platform.CloseContextActionsSignalName); + + var platform = _listView.Platform; + if (platform.GetType() == typeof(AppCompat.Platform)) + MessagingCenter.Unsubscribe(this, Platform.CloseContextActionsSignalName); + else + MessagingCenter.Unsubscribe(this, Platform.CloseContextActionsSignalName); + _realListView.OnItemClickListener = null; _realListView.OnItemLongClickListener = null; -- 2.7.4