Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.Forms.Core.UITests;
using NUnit.Framework;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ManualReview)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 15066, "[Bug] StackLayout's layout inside ScrollView is not updated properly when adding children", PlatformAffected.Android)]
public class Issue15066 : TestContentPage
{
protected override void Init()
{
Button addButton = new Button()
{
Text = "Add",
};
Label testInstructionsLabel = new Label()
{
Text = "Click the 'Add' button until the height of the dark green StackLayout is larger than the height of the page. " +
"Then scroll to the end of the page. " +
"If there is a dark blue gap at the end of the page, the test has failed.",
HorizontalTextAlignment = TextAlignment.Center,
};
StackLayout containerStackLayout = new StackLayout()
{
BackgroundColor = Color.DarkGreen,
Children = { addButton, testInstructionsLabel },
};
addButton.Clicked += (_, __) =>
containerStackLayout.Children.Add(new StackLayout() { BackgroundColor = Color.Gray, HeightRequest = 40.0 });
Content = new ScrollView()
{
BackgroundColor = Color.DarkBlue,
Content = containerStackLayout,
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue14805.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11954.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13918.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue15066.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
Expand Down
7 changes: 0 additions & 7 deletions Xamarin.Forms.Core/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ public static IPlatformServices PlatformServices
set { s_platformServices = value; }
}

public static IPlatformInvalidate PlatformInvalidator { get; set; }

[EditorBrowsable(EditorBrowsableState.Never)]
public static IReadOnlyList<string> Flags { get; private set; }

Expand Down Expand Up @@ -287,10 +285,5 @@ public static class Styles

public static readonly Style CaptionStyle = new Style(typeof(Label)) { BaseResourceKey = CaptionStyleKey };
}

public static void Invalidate(VisualElement visualElement)
{
PlatformInvalidator?.Invalidate(visualElement);
}
}
}
8 changes: 0 additions & 8 deletions Xamarin.Forms.Core/IPlatformInvalidate.cs

This file was deleted.

10 changes: 2 additions & 8 deletions Xamarin.Forms.Core/Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ internal virtual void OnChildMeasureInvalidated(VisualElement child, Invalidatio

s_resolutionList.Add(new KeyValuePair<Layout, int>(this, GetElementDepth(this)));

if (Device.PlatformInvalidator == null && !s_relayoutInProgress)
if (!s_relayoutInProgress)
{
// Rather than recomputing the layout for each change as it happens, we accumulate them in
// s_resolutionList and schedule a single layout update operation to handle them all at once.
Expand All @@ -345,15 +345,9 @@ internal virtual void OnChildMeasureInvalidated(VisualElement child, Invalidatio
Device.BeginInvokeOnMainThread(ResolveLayoutChanges);
}
}
else
{
// If the platform supports PlatformServices2, queueing is unnecessary; the layout changes
// will be handled during the Layout's next Measure/Arrange pass
Device.Invalidate(this);
}
}

public void ResolveLayoutChanges()
internal void ResolveLayoutChanges()
{
s_relayoutInProgress = false;

Expand Down
1 change: 0 additions & 1 deletion Xamarin.Forms.Core/VisualElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,6 @@ public void BatchCommit()
if (!Batched)
{
BatchCommitted?.Invoke(this, new EventArg<VisualElement>(this));
Device.Invalidate(this);
}
}

Expand Down
19 changes: 2 additions & 17 deletions Xamarin.Forms.Platform.Android/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,7 @@ static void SetupInit(
// because AndroidPlatformServices needs a current activity to launch URIs from
Profile.FramePartition("Device.PlatformServices");

var androidServices = new AndroidPlatformServices(activity);

Device.PlatformServices = androidServices;
Device.PlatformInvalidator = androidServices;
Device.PlatformServices = new AndroidPlatformServices(activity);

// use field and not property to avoid exception in getter
if (Device.info != null)
Expand Down Expand Up @@ -645,7 +642,7 @@ protected override Expression VisitMember(MemberExpression node)
}
}

class AndroidPlatformServices : IPlatformServices, IPlatformInvalidate
class AndroidPlatformServices : IPlatformServices
{
double _buttonDefaultSize;
double _editTextDefaultSize;
Expand Down Expand Up @@ -952,18 +949,6 @@ public SizeRequest GetNativeSize(VisualElement view, double widthConstraint, dou
return Platform.Android.Platform.GetNativeSize(view, widthConstraint, heightConstraint);
}

public void Invalidate(VisualElement visualElement)
{
var renderer = visualElement.GetRenderer();
if (renderer == null || renderer.View.IsDisposed())
{
return;
}

renderer.View.Invalidate();
renderer.View.RequestLayout();
}

public OSAppTheme RequestedTheme
{
get
Expand Down
10 changes: 0 additions & 10 deletions Xamarin.Forms.Platform.Android/VisualElementRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,5 @@ internal virtual void SendVisualElementInitialized(VisualElement element, AView

void IVisualElementRenderer.SetLabelFor(int? id)
=> ViewCompat.SetLabelFor(this, id ?? ViewCompat.GetLabelFor(this));

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (Element is Layout layout)
{
layout.ResolveLayoutChanges();
}

base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
3 changes: 0 additions & 3 deletions Xamarin.Forms.Platform.Android/VisualElementTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,6 @@ void UpdateIsVisible()
aview.Visibility = ViewStates.Visible;
if (!view.IsVisible && aview.Visibility != ViewStates.Gone)
aview.Visibility = ViewStates.Gone;

aview.Invalidate();
aview.RequestLayout();
}

void UpdateNativeView(object sender, EventArgs e)
Expand Down
5 changes: 1 addition & 4 deletions Xamarin.Forms.Platform.UAP/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,8 @@ public static void Init(IActivatedEventArgs launchActivatedEventArgs, IEnumerabl
Device.SetIdiom(TargetIdiom.Tablet);
Device.SetFlowDirection(GetFlowDirection());

var platformServices = new WindowsPlatformServices(Window.Current.Dispatcher);
Device.PlatformServices = new WindowsPlatformServices(Window.Current.Dispatcher);

Device.PlatformServices = platformServices;
Device.PlatformInvalidator = platformServices;

Device.SetFlags(s_flags);
Device.Info = new WindowsDeviceInfo();

Expand Down
5 changes: 0 additions & 5 deletions Xamarin.Forms.Platform.UAP/VisualElementRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,6 @@ protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Si
if (Element == null || availableSize.Width * availableSize.Height == 0)
return new Windows.Foundation.Size(0, 0);

if (Element is Layout layout)
{
layout.ResolveLayoutChanges();
}

Element.IsInNativeLayout = true;

for (var i = 0; i < ElementController.LogicalChildren.Count; i++)
Expand Down
13 changes: 1 addition & 12 deletions Xamarin.Forms.Platform.UAP/WindowsBasePlatformServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

namespace Xamarin.Forms.Platform.UWP
{
internal abstract class WindowsBasePlatformServices : IPlatformServices, IPlatformInvalidate
internal abstract class WindowsBasePlatformServices : IPlatformServices
{
const string WrongThreadError = "RPC_E_WRONG_THREAD";
readonly CoreDispatcher _dispatcher;
Expand Down Expand Up @@ -256,17 +256,6 @@ await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
return await taskCompletionSource.Task;
}

public void Invalidate(VisualElement visualElement)
{
var renderer = Platform.GetRenderer(visualElement);
if (renderer == null)
{
return;
}

renderer.ContainerElement.InvalidateMeasure();
}

public OSAppTheme RequestedTheme => Windows.UI.Xaml.Application.Current.RequestedTheme == ApplicationTheme.Dark ? OSAppTheme.Dark : OSAppTheme.Light;
}
}
20 changes: 1 addition & 19 deletions Xamarin.Forms.Platform.iOS/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,9 @@ public static void Init()
}
#endif
Device.SetFlags(s_flags);
var platformServices = new IOSPlatformServices();

Device.PlatformServices = platformServices;
Device.PlatformServices = new IOSPlatformServices();

#if __MOBILE__
Device.PlatformInvalidator = platformServices;
Device.Info = new IOSDeviceInfo();
#else
Device.Info = new Platform.macOS.MacDeviceInfo();
Expand Down Expand Up @@ -265,9 +262,6 @@ protected override Expression VisitMember(MemberExpression node)
}

class IOSPlatformServices : IPlatformServices
#if __MOBILE__
, IPlatformInvalidate
#endif
{
readonly double _fontScalingFactor = 1;
public IOSPlatformServices()
Expand Down Expand Up @@ -824,18 +818,6 @@ static UIViewController GetCurrentViewController(bool throwIfNull = true)

return viewController;
}

public void Invalidate(VisualElement visualElement)
{
var renderer = Platform.iOS.Platform.GetRenderer(visualElement);

if (renderer == null)
{
return;
}

renderer.NativeView.SetNeedsLayout();
}
#endif
}
}
Expand Down
11 changes: 0 additions & 11 deletions Xamarin.Forms.Platform.iOS/VisualElementRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,24 +313,13 @@ public void SetElement(TElement element)

#if __MOBILE__

void ResolveLayoutChanges()
{
if (Element is Layout layout)
{
layout.ResolveLayoutChanges();
}
}

public override SizeF SizeThatFits(SizeF size)
{
ResolveLayoutChanges();
return new SizeF(0, 0);
}

public override void LayoutSubviews()
{
ResolveLayoutChanges();

base.LayoutSubviews();

if (_blur != null && Superview != null)
Expand Down