diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue20348.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue20348.cs new file mode 100644 index 000000000000..79d0d9d4bcbc --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue20348.cs @@ -0,0 +1,79 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 20348, "SearchBar text incorrectly copied between multiple SearchBars on Android after back navigation", PlatformAffected.Android)] +public class Issue20348 : NavigationPage +{ + public Issue20348() : base(new MainPage()) + { + } + + public class MainPage : ContentPage + { + public MainPage() + { + SearchBar firstSearchBar = new SearchBar + { + AutomationId = "FirstSearchBar" + }; + + Label firstSearchBarTextLabel = new Label + { + AutomationId = "FirstSearchBarText", + Text = "Pass" + }; + + firstSearchBar.TextChanged += (s, e) => + { + firstSearchBarTextLabel.Text = string.IsNullOrEmpty(e.NewTextValue) + ? "Pass" + : "Fail"; + }; + + SearchBar secondSearchBar = new SearchBar + { + AutomationId = "SecondSearchBar" + }; + + Button navigateButton = new Button + { + Text = "Navigate", + AutomationId = "NavigateButton" + }; + + navigateButton.Clicked += async (s, e) => + { + await Navigation.PushAsync(new SecondPage()); + }; + + Label descriptionLabel = new Label + { + Text = "Test passes if SecondSearchBar text is NOT applied to FirstSearchBar after typing in SecondSearchBar, navigating to page 2, and pressing back.", + FontSize = 12, + TextColor = Colors.Gray, + HorizontalTextAlignment = TextAlignment.Center + }; + + Content = new VerticalStackLayout + { + Padding = 20, + Spacing = 10, + Children = { descriptionLabel, firstSearchBar, firstSearchBarTextLabel, secondSearchBar, navigateButton } + }; + } + } + + public class SecondPage : ContentPage + { + public SecondPage() + { + Title = "Second Page"; + Content = new Label + { + Text = "Second Page", + AutomationId = "SecondPageLabel", + HorizontalOptions = LayoutOptions.Center, + VerticalOptions = LayoutOptions.Center + }; + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20348.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20348.cs new file mode 100644 index 000000000000..b1de33c9be0f --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20348.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue20348 : _IssuesUITest +{ + public override string Issue => "SearchBar text incorrectly copied between multiple SearchBars on Android after back navigation"; + + public Issue20348(TestDevice device) : base(device) { } + + [Test] + [Category(UITestCategories.SearchBar)] + public void SearchBarTextShouldNotBleedToOtherInstances() + { + App.WaitForElement("FirstSearchBar"); + App.WaitForElement("SecondSearchBar"); + + App.EnterText("SecondSearchBar", "TestText"); + App.Tap("NavigateButton"); + + App.WaitForElement("SecondPageLabel"); + this.Back(); + App.WaitForElement("FirstSearchBarText"); + + var result = App.FindElement("FirstSearchBarText").GetText(); + Assert.That(result, Is.EqualTo("Pass"), + "First SearchBar should be empty after back navigation — Android state save/restore should not bleed text from other SearchBar instances"); + } +} diff --git a/src/Core/src/Platform/Android/MauiSearchView.cs b/src/Core/src/Platform/Android/MauiSearchView.cs index 7c730308ae23..c2f868d28d6f 100644 --- a/src/Core/src/Platform/Android/MauiSearchView.cs +++ b/src/Core/src/Platform/Android/MauiSearchView.cs @@ -22,6 +22,16 @@ void Initialize() _queryEditor = this.GetFirstChildOfType(); + // Disable Android's built-in instance state saving on the internal EditText + // to prevent query text from being incorrectly restored across multiple + // SearchView instances during navigation. The EditText shares a fixed + // resource ID (search_src_text) across all SearchViews, causing state + // to bleed between instances. + if (_queryEditor is not null) + { + _queryEditor.SaveEnabled = false; + } + if (_queryEditor?.LayoutParameters is LinearLayout.LayoutParams layoutParams) { layoutParams.Height = LinearLayout.LayoutParams.MatchParent;