diff --git a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.android.cs b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.android.cs index 0e62fe725..7758abcd5 100644 --- a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.android.cs +++ b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.android.cs @@ -2,7 +2,9 @@ using Android.Graphics.Drawables; using Android.OS; using Android.Views; +using AndroidX.AppCompat.Widget; using Microsoft.Maui.Platform; +using static Android.Views.View; using AColorRes = Android.Resource.Color; using APoint = Android.Graphics.Point; using ARect = Android.Graphics.Rect; @@ -174,14 +176,26 @@ static void CalculateSizes(IPopup popup, Context context, Size windowSize, ref i ArgumentNullException.ThrowIfNull(popup.Content); var density = context.Resources?.DisplayMetrics?.Density ?? throw new InvalidOperationException($"Unable to determine density. {nameof(context.Resources.DisplayMetrics)} cannot be null"); + var view = popup.Content.ToPlatform(); if (popup.Size.IsZero) { if (double.IsNaN(popup.Content.Width) || double.IsNaN(popup.Content.Height)) { - var size = popup.Content.Measure(windowSize.Width / density, windowSize.Height / density); - realContentWidth = (int)context.ToPixels(size.Width); - realContentHeight = (int)context.ToPixels(size.Height); + if (view is not null) + { + bool isRootView = true; + Measure( + view, + (int)(double.IsNaN(popup.Content.Width) ? windowSize.Width : (int)context.ToPixels(popup.Content.Width)), + (int)(double.IsNaN(popup.Content.Height) ? windowSize.Height : (int)context.ToPixels(popup.Content.Height)), + double.IsNaN(popup.Content.Width) && popup.HorizontalOptions != LayoutAlignment.Fill, + double.IsNaN(popup.Content.Height) && popup.VerticalOptions != LayoutAlignment.Fill, + ref isRootView + ); + realContentWidth = view.MeasuredWidth; + realContentHeight = view.MeasuredHeight; + } if (double.IsNaN(popup.Content.Width)) { @@ -200,12 +214,20 @@ static void CalculateSizes(IPopup popup, Context context, Size windowSize, ref i } else { - realWidth = (int)context.ToPixels(popup.Size.Width); - realHeight = (int)context.ToPixels(popup.Size.Height); - - var size = popup.Content.Measure(popup.Size.Width, popup.Size.Height); - realContentWidth = (int)context.ToPixels(size.Width); - realContentHeight = (int)context.ToPixels(size.Height); + if (view is not null) + { + bool isRootView = true; + Measure( + view, + (int)context.ToPixels(popup.Size.Width), + (int)context.ToPixels(popup.Size.Height), + false, + false, + ref isRootView + ); + realContentWidth = view.MeasuredWidth; + realContentHeight = view.MeasuredHeight; + } } realWidth = Math.Min(realWidth is 0 ? realContentWidth : realWidth, (int)windowSize.Width); @@ -218,6 +240,40 @@ static void CalculateSizes(IPopup popup, Context context, Size windowSize, ref i } } + static void Measure(AView view, int width, int height, bool isNanWidth, bool isNanHeight, ref bool isRootView) + { + if (isRootView) + { + isRootView = false; + view.Measure( + MeasureSpec.MakeMeasureSpec(width, !isNanWidth ? MeasureSpecMode.Exactly : MeasureSpecMode.AtMost), + MeasureSpec.MakeMeasureSpec(height, !isNanHeight ? MeasureSpecMode.Exactly : MeasureSpecMode.AtMost) + ); + } + + if (view is AppCompatTextView) + { + // https://github.com/dotnet/maui/issues/2019 + // https://github.com/dotnet/maui/pull/2059 + var layoutParams = view.LayoutParameters; + view.Measure( + MeasureSpec.MakeMeasureSpec(width, (layoutParams?.Width == LinearLayout.LayoutParams.WrapContent && !isNanWidth) ? MeasureSpecMode.Exactly : MeasureSpecMode.Unspecified), + MeasureSpec.MakeMeasureSpec(height, (layoutParams?.Height == LinearLayout.LayoutParams.WrapContent && !isNanHeight) ? MeasureSpecMode.Exactly : MeasureSpecMode.Unspecified) + ); + } + + if (view is ViewGroup viewGroup) + { + for (int i = 0; i < viewGroup.ChildCount; i++) + { + if (viewGroup.GetChildAt(i) is AView childView) + { + Measure(childView, width, height, isNanWidth, isNanHeight, ref isRootView); + } + } + } + } + static Size GetWindowSize(IWindowManager? windowManager, ViewGroup decorView) { ArgumentNullException.ThrowIfNull(windowManager); diff --git a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.macios.cs b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.macios.cs index 72a45f8ac..f96a8e4b1 100644 --- a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.macios.cs +++ b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.macios.cs @@ -43,7 +43,7 @@ public static void SetSize(this MauiPopup mauiPopup, in IPopup popup) if (double.IsNaN(popup.Content.Width) || double.IsNaN(popup.Content.Height)) { var content = popup.Content.ToPlatform(popup.Handler?.MauiContext ?? throw new InvalidOperationException($"{nameof(popup.Handler.MauiContext)} Cannot Be Null")); - var contentSize = content.SizeThatFits(new CGSize(frame.Width, frame.Height)); + var contentSize = content.SizeThatFits(new CGSize(double.IsNaN(popup.Content.Width) ? frame.Width : popup.Content.Width, double.IsNaN(popup.Content.Height) ? frame.Height : popup.Content.Height)); var width = contentSize.Width; var height = contentSize.Height; diff --git a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs index 447ac39dd..672e7eca1 100644 --- a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs +++ b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs @@ -79,7 +79,7 @@ public static void SetSize(this Popup mauiPopup, IPopup popup, IMauiContext? mau { if (double.IsNaN(popup.Content.Width) || (double.IsNaN(popup.Content.Height))) { - currentSize = popup.Content.Measure(popupParent.Bounds.Width, popupParent.Bounds.Height); + currentSize = popup.Content.Measure(double.IsNaN(popup.Content.Width) ? popupParent.Bounds.Width : popup.Content.Width, double.IsNaN(popup.Content.Height) ? popupParent.Bounds.Height : popup.Content.Height); if (double.IsNaN(popup.Content.Width)) {