Skip to content

Commit

Permalink
fix(droid): add workaround for NavView leaving blank on IsBackButtonV…
Browse files Browse the repository at this point in the history
…isible update
  • Loading branch information
Xiaoy312 committed Feb 13, 2025
1 parent 2a674e0 commit e12cc8d
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
using System.Threading.Tasks;
#if WINAPPSDK
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Windows.UI;
using Uno.Extensions;
using Uno.Extensions.Specialized;
using Uno.UI.Extensions;
#elif __IOS__
using Uno.UI.RuntimeTests.Helpers;

using static Private.Infrastructure.TestServices;
using MUXC = Microsoft/* UWP don't rename */.UI.Xaml.Controls;

#if __IOS__
using UIKit;
#elif __MACOS__
using AppKit;
#else
#endif
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using static Private.Infrastructure.TestServices;
using Windows.UI;
using Microsoft.UI.Xaml.Media;
using Uno.UI.RuntimeTests.Helpers;

namespace Uno.UI.RuntimeTests.Tests.Microsoft_UI_Xaml_Controls
{
Expand Down Expand Up @@ -73,5 +79,102 @@ public async Task When_SelectedItem_Set_Before_Load_And_Theme_Changed()
#endif
}
}

[TestMethod]
public async Task When_IsBackButtonVisible_Toggled()
{
// unoplatform/uno#19516
// droid-specific: There is a bug where setting IsBackButtonVisible would "lock" the size of all NVIs
// preventing resizing on items expansion/collapse.

var sut = new MUXC.NavigationView()
{
Height = 500,
IsBackButtonVisible = MUXC.NavigationViewBackButtonVisible.Collapsed,
IsPaneToggleButtonVisible = false,
PaneDisplayMode = NavigationViewPaneDisplayMode.Left,
CompactModeThresholdWidth = 10,
ExpandedModeThresholdWidth = 50,
};
sut.ItemInvoked += (s, e) =>
{
// manual trigger for deepest/inner-most items
if (e.InvokedItemContainer is NavigationViewItem nvi &&
nvi.MenuItems.Count == 0)
{
sut.IsBackButtonVisible = NavigationViewBackButtonVisible.Visible;
}
};

var nvis = new Dictionary<string, NavigationViewItem>();
//AddItems(sut.MenuItems, "", count: 4, depth: 1, maxDepth: 2);

Check warning on line 110 in src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_NavigationView.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_NavigationView.cs#L110

Remove this commented out code.
AddItems(sut.MenuItems, "", count: 3, depth: 1, maxDepth: 3);
void AddItems(IList<object> target, string prefix, int count, int depth, int maxDepth)
{
for (int i = 0; i < count; i++)
{
var header = prefix + (char)('A' + i);
var item = new NavigationViewItem() { Content = header };

if (depth < maxDepth) AddItems(item.MenuItems, header, count, depth + 1, maxDepth);

Check failure on line 119 in src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_NavigationView.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_NavigationView.cs#L119

Add curly braces around the nested statement(s) in this 'if' block.

target.Add(item);
nvis.Add(header, item);
}
}

// for debugging
var panel = new StackPanel();
void AddTestButton(string label, Action action)
{
var button = new Button() { Content = label };
button.Click += (s, e) => action();
panel.Children.Add(button);
}
AddTestButton("InvalidateMeasure", () =>
{
foreach (var ir in sut.EnumerateDescendants().OfType<ItemsRepeater>())
{
ir.InvalidateMeasure();
}
});
AddTestButton("IsBackButtonVisible toggle", () => sut.IsBackButtonVisible = sut.IsBackButtonVisible == NavigationViewBackButtonVisible.Collapsed
? NavigationViewBackButtonVisible.Visible
: NavigationViewBackButtonVisible.Collapsed);
panel.Children.Add(sut);

await UITestHelper.Load(panel, x => x.IsLoaded);

var initialHeight = nvis["B"].ActualHeight;

nvis["B"].IsExpanded = true;
await UITestHelper.WaitForIdle();
var partiallyExpandedHeight = nvis["B"].ActualHeight;

nvis["BB"].IsExpanded = true;
await UITestHelper.WaitForIdle();
var fullyExpandedHeight = nvis["B"].ActualHeight;

// trigger the bug
await Task.Delay(2000); // necessary
sut.IsBackButtonVisible = NavigationViewBackButtonVisible.Visible;
await UITestHelper.WaitForIdle();

nvis["BB"].IsExpanded = false;
await UITestHelper.WaitForIdle();
var partiallyCollapsedHeight = nvis["B"].ActualHeight;

nvis["B"].IsExpanded = false;
await UITestHelper.WaitForIdle();
var fullyCollapsedHeight = nvis["B"].ActualHeight;

// sanity check
Assert.IsTrue(initialHeight < partiallyExpandedHeight, $"Expanding 'B' should increase item 'B' height: {initialHeight} -> {partiallyExpandedHeight}");
Assert.IsTrue(partiallyExpandedHeight < fullyExpandedHeight, $"Expanding 'BB' should increase item 'B' height: {partiallyExpandedHeight} -> {fullyExpandedHeight}");

// verifying fix
Assert.IsTrue(fullyExpandedHeight > partiallyCollapsedHeight, $"Collapsing 'BB' should reduce item 'B' height: {fullyExpandedHeight} -> {partiallyCollapsedHeight}");
Assert.IsTrue(partiallyCollapsedHeight > fullyCollapsedHeight, $"Collapsing 'B' should reduce item 'B' height: {partiallyCollapsedHeight} -> {fullyCollapsedHeight}");
}
}
}
10 changes: 10 additions & 0 deletions src/Uno.UI/FeatureConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -929,5 +929,15 @@ public static bool IsEdgeToEdgeEnabled
}
}
#endif

public static class NavigationView
{
#if __ANDROID__
/// <summary>
/// Workaround for unoplatform/uno#19516 where toggling IsBackButtonVisible would stop NVIs from updating their layout/size when expanded/collapsed.
/// </summary>
public static bool EnableUno19516Workaround { get; set; } = true;
#endif
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Numerics;
using Microsoft/* UWP don't rename */.UI.Xaml.Automation.Peers;
using Microsoft/* UWP don't rename */.UI.Xaml.Controls.AnimatedVisuals;
using Uno.Disposables;
using Uno.Foundation.Logging;
using Uno.UI;
using Uno.UI.DataBinding;
using Uno.UI.Extensions;
using Uno.UI.Helpers.WinUI;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
Expand Down Expand Up @@ -4353,6 +4356,17 @@ private void OnPropertyChanged(DependencyPropertyChangedEventArgs args)
{
backButton.UpdateLayout();
}

// workaround for unoplatform/uno#19516 where toggling IsBackButtonVisible would stop NVIs from updating their layout/size when expanded/collapsed.
if (FeatureConfiguration.NavigationView.EnableUno19516Workaround &&

Check failure on line 4361 in src/Uno.UI/Microsoft/UI/Xaml/Controls/NavigationView/NavigationView.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'FeatureConfiguration.NavigationView' does not contain a definition for 'EnableUno19516Workaround'

Check failure on line 4361 in src/Uno.UI/Microsoft/UI/Xaml/Controls/NavigationView/NavigationView.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'FeatureConfiguration.NavigationView' does not contain a definition for 'EnableUno19516Workaround'
m_appliedTemplate && IsLoaded)
{
foreach (var ir in this.EnumerateDescendants().OfType<ItemsRepeater>())
{
ir.InvalidateMeasure();
}
}

UpdatePaneLayout();
}

Expand Down

0 comments on commit e12cc8d

Please sign in to comment.