Skip to content

[Android] Use a GeneralWrapperView for a Flyout View#26461

Open
kubaflo wants to merge 1 commit intodotnet:mainfrom
kubaflo:fix-26392
Open

[Android] Use a GeneralWrapperView for a Flyout View#26461
kubaflo wants to merge 1 commit intodotnet:mainfrom
kubaflo:fix-26392

Conversation

@kubaflo
Copy link
Contributor

@kubaflo kubaflo commented Dec 8, 2024

Description of Change

Introduction of GeneralWrapperView:

Added a new GeneralWrapperView class in src/Controls/src/Core/Platform/Android/GeneralWrapperView.cs to handle the wrapping of views, enabling better measurement and arrangement. Like in this PR: #26513

Issues Fixed

Fixes #26392

Before After
Screen.Recording.2024-12-08.at.14.51.08.mov
Screen.Recording.2024-12-08.at.14.50.14.mov

@kubaflo kubaflo requested a review from a team as a code owner December 8, 2024 14:02
@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Dec 8, 2024
Copy link
Member

@rmarinho rmarinho left a comment

Choose a reason for hiding this comment

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

Can we add a test ? There/s no override for this ? we need to add the listener ?

Don t we need t clear the listener on dispose?

@kubaflo
Copy link
Contributor Author

kubaflo commented Dec 9, 2024

@rmarinho
So... Android uses com.google.android.material.navigation.NavigationView as a drawer that I bet has some configuration responsible for intercepting a click.

This is from the default Android studio template:

But we use a view which is of type LayoutGroup - ContentPage is converted to it after .ToPlatform() I think.
So it doesn't intercept a click without android:clickable = true

Also when I replaced com.google.android.material.navigation.NavigationView with LinearLayout in the default Android studio app, it also didn't intercept a click without android:clickable = true

But @PureWeen wrote that setting android:clickable = true would break accessibility

I wonder if setting the listener is the right approach then

Copy link
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.

Copilot reviewed 2 out of 3 changed files in this pull request and generated no suggestions.

Files not reviewed (1)
  • src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt: Language not supported

@kubaflo kubaflo force-pushed the fix-26392 branch 2 times, most recently from e064adf to ec7e41d Compare December 10, 2024 17:03
platformHandler.UpdateFlyoutBehavior();
}

internal class FlyoutContainer : ContentViewGroup
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this?

And we can reuse this various places.

I think also in the flyoutview code you'll want to remove the _flyoutView from the wrapper view

class GeneralWrapperView : ContentViewGroup, ICrossPlatformLayout
	{
		public WeakReference<IView>? ChildView { get; private set; }

		public GeneralWrapperView(Context context, IView childView, IMauiContext mauiContext) : base(context)
		{
			CrossPlatformLayout = this;
			UpdatePlatformView(childView, mauiContext);
		}
		
		public void Disconnect()
		{
			if (ChildView == null || !ChildView.TryGetTarget(out var childView))
			{
				return;
			}

			if (ChildCount > 0)
			{
				GetChildAt(0)?.RemoveFromParent();
			}

			childView.DisconnectHandlers();
		}

		public void UpdatePlatformView(IView? newChildView, IMauiContext mauiContext)
		{
			if (ChildCount > 0)
			{
				GetChildAt(0)?.RemoveFromParent();
			}

			if (newChildView is null)
			{
				ChildView = null;
				return;
			}

			ChildView = new (newChildView);
			var nativeView = newChildView.ToPlatform(mauiContext);
			AddView(nativeView);
		}

		Graphics.Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double heightConstraint)
		{
			if (ChildView == null || !ChildView.TryGetTarget(out var childView))
				return Graphics.Size.Zero;

			return childView.Arrange(new Graphics.Rect(0, 0, widthConstraint, heightConstraint));
		}

		public Graphics.Size CrossPlatformArrange(Graphics.Rect bounds)
		{
			if (ChildView == null || !ChildView.TryGetTarget(out var childView))
				return Graphics.Size.Zero;

			return childView.Measure(bounds.Width, bounds.Height);
		}
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, it looks good, but I switched
return childView.Arrange(new Graphics.Rect(0, 0, widthConstraint, heightConstraint));
with
return childView.Measure(bounds.Width, bounds.Height);

@kubaflo kubaflo changed the title [Android] Click on flyout clicks on page behind - fix [Android] Use a GeneralWrapperView for a Flyout View Dec 11, 2024
@kubaflo kubaflo requested review from PureWeen and rmarinho December 11, 2024 00:16
@kubaflo kubaflo requested a review from jfversluis as a code owner December 11, 2024 01:11
@PureWeen
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@samhouts samhouts requested a review from Copilot December 13, 2024 22:30
Copy link
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.

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

Comments suppressed due to low confidence (1)

src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cs:383

  • The OnTouchEvent method override in the FlyoutContainer class should be covered by a test case to ensure that clicks on the flyout do not propagate to the views behind it.
public override bool OnTouchEvent(MotionEvent? e)

@samhouts samhouts requested a review from Copilot December 13, 2024 22:35
Copy link
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.

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

Comments suppressed due to low confidence (1)

src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cs:383

  • The new OnTouchEvent method in the FlyoutContainer class should be covered by a unit test to ensure that it correctly disables click-through on items behind the drawer.
public override bool OnTouchEvent(MotionEvent? e)

@kubaflo kubaflo self-assigned this Mar 30, 2025
@ondrej-krc-jediny
Copy link

Hello, it looks like this PR has been inactive for a while. I’d really appreciate this being wrapped up, as the issue it addresses is still relevant. Is there any chance this will be fixed in near future? Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-flyout Flyout community ✨ Community Contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Click on flyout clicks on page behind

6 participants