Skip to content

[Android] Fix Shadow property affecting transform matrix.#32962

Open
Shalini-Ashokan wants to merge 9 commits into
dotnet:mainfrom
Shalini-Ashokan:fix-32731
Open

[Android] Fix Shadow property affecting transform matrix.#32962
Shalini-Ashokan wants to merge 9 commits into
dotnet:mainfrom
Shalini-Ashokan:fix-32731

Conversation

@Shalini-Ashokan
Copy link
Copy Markdown
Contributor

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 if this change resolves your issue. Thank you!

Issue Details

When a Shadow property is applied to any visual element on Android (Border, Label, Image, etc.), transform properties (Scale, Rotation, Translation) do not work correctly.

Root Cause

When a view has a Shadow, Android wraps it in a container that draws the shadow. The problem was that transforms were applied to the content inside the container, so the content would scale/rotate but the shadow stayed in place.

Description of Change

Modified the initialization logic to detect when a view is wrapped in a container and apply transforms to the container instead. This ensures shadows transform together with their content, fixing the issue for all controls that support Shadow properties.

Validated the behavior in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Issues Fixed

Fixes #32731

Test case

The test case is included in this PR.

Output ScreenShot

Before After
32731-Before-Fix.mov
32731-After-Fix.mov

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Dec 2, 2025
@sheiksyedm sheiksyedm added area-animation Animation, Transitions, Transforms platform/android labels Dec 3, 2025
@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-failed AI could not verify tests catch the bug 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 Feb 18, 2026
@Shalini-Ashokan
Copy link
Copy Markdown
Contributor Author

The test is already added in this PR. This PR test case covers all scenarios of the current issue also. The issues are the same but created PR for platform-specific. I manually ensured the test case. It is working fine. The AI concern is not valid because the test is not added due to the test case addition. Once this PR is merged, that test case covers both issues.

@kubaflo kubaflo added s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-win AI found a better alternative fix than the PR s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-failed AI could not verify tests catch the bug labels Feb 20, 2026
@MauiBot MauiBot added the s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) label Mar 28, 2026
@Shalini-Ashokan
Copy link
Copy Markdown
Contributor Author

🚦 Gate — Test Verification

📊 Expand Full Gate656a6da · modified the fix

The gate failed because the test was added in another PR, as mentioned in my previous comment

@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 and removed s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels Apr 3, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 3, 2026

@Shalini-Ashokan could you please duplicate the test for this PR?

@sheiksyedm sheiksyedm marked this pull request as ready for review April 6, 2026 06:46
Copilot AI review requested due to automatic review settings April 6, 2026 06:46
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

Fixes Android behavior where applying Shadow wraps the native view, causing transforms (scale/rotation/translation/anchor) to be applied to the inner view instead of the shadow-drawing wrapper.

Changes:

  • Transfer existing transform properties from the inner Android view to the WrapperView when the container is created (and back when removed).
  • Add an Android ResetTransform helper to clear transforms on the source view after transfer.
  • Update Android batched initialization to initialize the wrapper when a view is wrapped.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Core/src/Platform/Android/WrapperView.cs Transfers transform-related properties between inner view and wrapper on container add/remove.
src/Core/src/Platform/Android/ViewExtensions.cs Adds ResetTransform helper used during transform transfer.
src/Core/src/Handlers/View/ViewHandler.cs Adjusts Android batched initialization to target the wrapper when present.

Comment on lines 203 to 207
// If the view is wrapped in a WrapperView (for Shadow/Clip), apply batched properties to the wrapper instead.
var viewToInitialize = pv.Parent is WrapperView ? (PlatformView)pv.Parent : pv;
viewToInitialize.Initialize(view);
}
}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

MapInitializeBatchedProperties now calls Initialize(view) on the WrapperView when the platform view is wrapped. Android.ViewExtensions.Initialize batches more than transforms (e.g., enabled, minimumHeight, minimumWidth, alpha), but later property updates (e.g., MapIsEnabled, MapMinimumHeight/Width) still target handler.PlatformView (the inner view). This can leave the wrapper and inner view out of sync (notably: if the view starts disabled and is later enabled, the wrapper may remain disabled and continue blocking input). Consider keeping Initialize(view) on the inner PlatformView and then transferring only the transform-related properties (translation/scale/rotation/pivot) to the wrapper (resetting the inner transforms), or otherwise ensure non-transform properties remain applied consistently to the inner view and/or are updated on the wrapper too.

Suggested change
// If the view is wrapped in a WrapperView (for Shadow/Clip), apply batched properties to the wrapper instead.
var viewToInitialize = pv.Parent is WrapperView ? (PlatformView)pv.Parent : pv;
viewToInitialize.Initialize(view);
}
}
pv.Initialize(view);
if (pv.Parent is WrapperView wrapper)
TransferBatchedTransformsToWrapper(pv, wrapper);
}
}
static void TransferBatchedTransformsToWrapper(PlatformView platformView, WrapperView wrapperView)
{
wrapperView.TranslationX = platformView.TranslationX;
wrapperView.TranslationY = platformView.TranslationY;
wrapperView.ScaleX = platformView.ScaleX;
wrapperView.ScaleY = platformView.ScaleY;
wrapperView.Rotation = platformView.Rotation;
wrapperView.RotationX = platformView.RotationX;
wrapperView.RotationY = platformView.RotationY;
wrapperView.PivotX = platformView.PivotX;
wrapperView.PivotY = platformView.PivotY;
platformView.TranslationX = 0;
platformView.TranslationY = 0;
platformView.ScaleX = 1;
platformView.ScaleY = 1;
platformView.Rotation = 0;
platformView.RotationX = 0;
platformView.RotationY = 0;
platformView.PivotX = 0;
platformView.PivotY = 0;
}

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 7, 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 -- 32962

Or

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

@Shalini-Ashokan
Copy link
Copy Markdown
Contributor Author

@Shalini-Ashokan could you please duplicate the test for this PR?

@kubaflo, I have added the test cases and verified them.

Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

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

One test failed

@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

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

Could you please review: #32962 (comment)

@Shalini-Ashokan
Copy link
Copy Markdown
Contributor Author

Could you please review: #32962 (comment)

@kubaflo, I addressed the AI concerns

@dotnet dotnet deleted a comment from MauiBot Apr 13, 2026
@dotnet dotnet deleted a comment from MauiBot Apr 13, 2026
@dotnet dotnet deleted a comment from rmarinho Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-animation Animation, Transitions, Transforms 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-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Applying Shadow property affects the properties in Visual Transform Matrix

7 participants