Fix 7181 | [Bug] Cannot update ToolbarItem text and icon (#8254) fixes #7181
authorFelipe Baltazar <felipe.dasilvabaltazar@gmail.com>
Tue, 5 Nov 2019 16:33:28 +0000 (13:33 -0300)
committerRui Marinho <me@ruimarinho.net>
Tue, 5 Nov 2019 16:33:28 +0000 (16:33 +0000)
* Created handler for Toolbaritem.OnPropertyChanged

* Code review ♻

* Code review ♻

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7181.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Platform.Android/Renderers/ShellToolbarTracker.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7181.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue7181.cs
new file mode 100644 (file)
index 0000000..c52af6a
--- /dev/null
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Xamarin.Forms.Internals;
+using Xamarin.Forms.CustomAttributes;
+
+#if UITEST
+using Xamarin.UITest;
+using NUnit.Framework;
+using Xamarin.Forms.Core.UITests;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 7181, "[Bug] Cannot update ToolbarItem text and icon", PlatformAffected.Android)]
+#if UITEST
+       [NUnit.Framework.Category(UITestCategories.Shell)]
+#endif
+       public class Issue7181 : TestShell
+       {
+               const string ToolbarBtn = "Toolbar button";
+               const string DefaultToolbarItemText = "Toolbar test";
+               const string AfterClickToolbarItemText = "Button Clicked";
+               const string SetToolbarIconBtn = "Set toolbar icon button";
+
+               int _clicks = 0;
+               ToolbarItem _toolbarItem;
+
+               protected override void Init()
+               {
+                       var page = CreateContentPage("Test page");
+
+                       _toolbarItem = new ToolbarItem(DefaultToolbarItemText, string.Empty, OnToolbarClicked)
+                       {
+                               AutomationId = ToolbarBtn
+                       };
+
+                       page.ToolbarItems.Add(_toolbarItem);
+                       page.Content = new StackLayout()
+                       {
+                               Children =
+                               {
+                                       new Label
+                                       {
+                                               Text = "You should be able to change toolbar text"
+                                       },
+                                       new Button
+                                       {
+                                               AutomationId = SetToolbarIconBtn,
+                                               Text = "Click to change toolbarIcon",
+                                               Command = new Command(()=> _toolbarItem.IconImageSource = "coffee.png" )
+                                       }
+                               }
+                       };
+               }
+
+               private void OnToolbarClicked() =>
+                       _toolbarItem.Text = $"{AfterClickToolbarItemText} {_clicks++}";
+
+#if UITEST && __ANDROID__
+               [Test]
+               public void ShellToolbarItemTests()
+               {
+                       var count = 0;
+                       var toolbarButton = RunningApp.WaitForElement(ToolbarBtn);
+                       Assert.AreEqual(toolbarButton[0].Text, DefaultToolbarItemText);
+
+                       for (int i = 0; i < 5; i++)
+                       {
+                               RunningApp.Tap(ToolbarBtn);
+
+                               toolbarButton = RunningApp.WaitForElement(ToolbarBtn);
+                               Assert.AreEqual($"{AfterClickToolbarItemText} {count++}", toolbarButton[0].Text);
+                       }
+
+                       RunningApp.Tap(SetToolbarIconBtn);
+               }
+#endif
+       }
+}
index bd90076..b753eed 100644 (file)
@@ -36,7 +36,8 @@
       <DependentUpon>Issue7048.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
-       <Compile Include="$(MSBuildThisFileDirectory)Issue5367.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Issue7181.cs" />
+         <Compile Include="$(MSBuildThisFileDirectory)Issue5367.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7253.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7581.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7621.xaml.cs">
index f11e1b3..a790a8a 100644 (file)
@@ -141,6 +141,13 @@ namespace Xamarin.Forms.Platform.Android
                        {
                                if (_backButtonBehavior != null)
                                        _backButtonBehavior.PropertyChanged -= OnBackButtonBehaviorChanged;
+
+                               if(Page?.ToolbarItems?.Count > 0)
+                               {
+                                       foreach (var item in Page.ToolbarItems)
+                                               item.PropertyChanged -= OnToolbarItemPropertyChanged;
+                               }
+
                                ((IShellController)_shellContext?.Shell)?.RemoveFlyoutBehaviorObserver(this);
 
                                UpdateTitleView(_shellContext.AndroidContext, _toolbar, null);
@@ -152,7 +159,7 @@ namespace Xamarin.Forms.Platform.Android
                                        _searchView.SearchConfirmed -= OnSearchConfirmed;
                                        _searchView.Dispose();
                                }
-        
+
                                _drawerToggle?.Dispose();
                        }
 
@@ -316,14 +323,14 @@ namespace Xamarin.Forms.Platform.Android
                        {
                                var customIcon = await context.GetFormsDrawableAsync(image);
 
-                               if(customIcon != null)
+                               if (customIcon != null)
                                        icon = new FlyoutIconDrawerDrawable(context, tintColor, customIcon, text);
                        }
 
                        if (!String.IsNullOrWhiteSpace(text) && icon == null)
                                icon = new FlyoutIconDrawerDrawable(context, tintColor, icon, text);
 
-                       if(icon == null)
+                       if (icon == null)
                        {
                                icon = new DrawerArrowDrawable(context.GetThemedContext());
                                icon.SetColorFilter(tintColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
@@ -336,10 +343,10 @@ namespace Xamarin.Forms.Platform.Android
                                _drawerToggle.DrawerIndicatorEnabled = false;
                                toolbar.NavigationIcon = icon;
                        }
-                       else if(_flyoutBehavior == FlyoutBehavior.Flyout)
+                       else if (_flyoutBehavior == FlyoutBehavior.Flyout)
                        {
                                _drawerToggle.DrawerIndicatorEnabled = isEnabled;
-                               if(isEnabled)
+                               if (isEnabled)
                                {
                                        _drawerToggle.DrawerArrowDrawable = icon;
                                        toolbar.NavigationIcon = null;
@@ -372,7 +379,7 @@ namespace Xamarin.Forms.Platform.Android
                        {
                                toolbar.NavigationContentDescription = shell.FlyoutIcon.AutomationId;
                        }
-                       else if(toolbar.SetNavigationContentDescription(_shellContext.Shell.FlyoutIcon) == null)
+                       else if (toolbar.SetNavigationContentDescription(_shellContext.Shell.FlyoutIcon) == null)
                        {
                                toolbar.SetNavigationContentDescription(R.String.Ok);
                        }
@@ -427,7 +434,7 @@ namespace Xamarin.Forms.Platform.Android
                                        _titleViewContainer = null;
                                }
                        }
-                       else if(_titleViewContainer == null)
+                       else if (_titleViewContainer == null)
                        {
                                _titleViewContainer = new ContainerView(context, titleView);
                                _titleViewContainer.MatchHeight = _titleViewContainer.MatchWidth = true;
@@ -454,6 +461,9 @@ namespace Xamarin.Forms.Platform.Android
 
                        foreach (var item in page.ToolbarItems)
                        {
+                               item.PropertyChanged -= OnToolbarItemPropertyChanged;
+                               item.PropertyChanged += OnToolbarItemPropertyChanged;
+
                                using (var title = new Java.Lang.String(item.Text))
                                {
                                        var menuitem = menu.Add(title);
@@ -466,11 +476,11 @@ namespace Xamarin.Forms.Platform.Android
                                                menuitem.SetShowAsAction(ShowAsAction.Always);
 
                                        menuitem.SetOnMenuItemClickListener(new GenericMenuClickListener(((IMenuItemController)item).Activate));
-                                       
-                                       if(TintColor != Color.Default)
+
+                                       if (TintColor != Color.Default)
                                        {
                                                var view = toolbar.FindViewById(menuitem.ItemId);
-                                               if (view is ATextView  textView)
+                                               if (view is ATextView textView)
                                                        textView.SetTextColor(TintColor.ToAndroid());
                                        }
 
@@ -538,6 +548,14 @@ namespace Xamarin.Forms.Platform.Android
                        menu.Dispose();
                }
 
+               void OnToolbarItemPropertyChanged(object sender, PropertyChangedEventArgs e)
+               {
+                       if (e.PropertyName == MenuItem.TextProperty.PropertyName)
+                               UpdateToolbarItems();
+                       if (e.PropertyName == MenuItem.IconImageSourceProperty.PropertyName)
+                               UpdateToolbarItems();
+               }
+
                void OnSearchViewAttachedToWindow(object sender, AView.ViewAttachedToWindowEventArgs e)
                {
                        // We only need to do this tint hack when using collapsed search handlers