Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Fix Flyout Footer measuring and Content Margin (#13157)
Browse files Browse the repository at this point in the history
* Fix Flyout Footer measuring and Content Margin

* - fix uwp tests and cleanup android code
  • Loading branch information
PureWeen committed Dec 17, 2020
1 parent f783f85 commit 298e62a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,15 @@ protected override void Init()
{
if (FlyoutHeaderTemplate == null)
{
FlyoutHeaderTemplate = new DataTemplate(() => new Label() { Text = "Header Template" });
FlyoutFooterTemplate = new DataTemplate(() => new Label() { Text = "Footer Template" });
FlyoutHeaderTemplate = new DataTemplate(() =>
{
return new Label() { Text = "Header Template" };
});
FlyoutFooterTemplate = new DataTemplate(() =>
{
return new Label() { Text = "Footer Template" };
});
}
else if (FlyoutHeaderTemplate != null)
{
Expand All @@ -76,8 +83,22 @@ protected override void Init()
}
else
{
FlyoutHeader = new Label() { Text = "Header View" };
FlyoutFooter = new Label() { Text = "Footer View" };
FlyoutHeader = new StackLayout()
{
Children = {
new Label() { Text = "Header" }
},
AutomationId = "Header View"
};
FlyoutFooter = new StackLayout()
{
Orientation = StackOrientation.Horizontal,
Children = {
new Label() { Text = "Footer" }
},
AutomationId = "Footer View"
};
}
}),
AutomationId = "ToggleHeaderFooter"
Expand Down Expand Up @@ -138,43 +159,42 @@ protected override void Init()
public void FlyoutTests()
{
RunningApp.WaitForElement("PageLoaded");
ShowFlyout();

// Verify Header an Footer show up at all
OpenFlyout("ToggleHeaderFooter");
TapInFlyout("ToggleHeaderFooter", makeSureFlyoutStaysOpen: true);
RunningApp.WaitForElement("Header View");
RunningApp.WaitForElement("Footer View");

// Verify Template takes priority over header footer
OpenFlyout("ToggleHeaderFooterTemplate");
TapInFlyout("ToggleHeaderFooterTemplate", makeSureFlyoutStaysOpen: true);
RunningApp.WaitForElement("Header Template");
RunningApp.WaitForElement("Footer Template");
RunningApp.WaitForNoElement("Header View");
RunningApp.WaitForNoElement("Footer View");

// Verify turning off Template shows Views again
OpenFlyout("ToggleHeaderFooterTemplate");
TapInFlyout("ToggleHeaderFooterTemplate", makeSureFlyoutStaysOpen: true);
RunningApp.WaitForElement("Header View");
RunningApp.WaitForElement("Footer View");
RunningApp.WaitForNoElement("Header Template");
RunningApp.WaitForNoElement("Footer Template");

// Verify turning off header/footer clear out views correctly
OpenFlyout("ToggleHeaderFooter");
TapInFlyout("ToggleHeaderFooter", makeSureFlyoutStaysOpen: true);
RunningApp.WaitForNoElement("Header Template");
RunningApp.WaitForNoElement("Footer Template");
RunningApp.WaitForNoElement("Header View");
RunningApp.WaitForNoElement("Footer View");

// verify header and footer react to size changes
OpenFlyout("ResizeHeaderFooter");
TapInFlyout("ResizeHeaderFooter", makeSureFlyoutStaysOpen: true);
var headerSizeSmall = RunningApp.WaitForElement("Header View")[0].Rect;
var footerSizeSmall = RunningApp.WaitForElement("Footer View")[0].Rect;
OpenFlyout("ResizeHeaderFooter");
TapInFlyout("ResizeHeaderFooter", makeSureFlyoutStaysOpen: true);
var headerSizeLarge = RunningApp.WaitForElement("Header View")[0].Rect;
var footerSizeLarge = RunningApp.WaitForElement("Footer View")[0].Rect;

OpenFlyout("ResizeHeaderFooter");
TapInFlyout("ResizeHeaderFooter", makeSureFlyoutStaysOpen: true);
var headerSizeSmall2 = RunningApp.WaitForElement("Header View")[0].Rect;
var footerSizeSmall2 = RunningApp.WaitForElement("Footer View")[0].Rect;

Expand All @@ -183,19 +203,6 @@ public void FlyoutTests()
Assert.AreEqual(headerSizeSmall2.Height, headerSizeSmall.Height);
Assert.AreEqual(footerSizeSmall2.Height, footerSizeSmall.Height);
}

void OpenFlyout(string text)
{
RunningApp.Tap(text);

#if __WINDOWS__
// UWP closes the flyout after selecting an item
System.Threading.Thread.Sleep(1000);
ShowFlyout();
#endif
}


#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public class ShellFlyoutTemplatedContentRenderer : Java.Lang.Object, IShellFlyou
int _actionBarHeight;
ScrollLayoutManager _layoutManager;

protected IShellContext ShellContext => _shellContext;
protected AView FooterView => _footerView?.NativeView;
protected AView View => _rootView;

public ShellFlyoutTemplatedContentRenderer(IShellContext shellContext)
{
_shellContext = shellContext;
Expand Down Expand Up @@ -152,7 +156,7 @@ protected virtual void OnShellPropertyChanged(object sender, PropertyChangedEven
UpdateFlyoutFooter();
}

void UpdateFlyoutHeader()
protected virtual void UpdateFlyoutHeader()
{
if (_headerView != null)
{
Expand Down Expand Up @@ -184,7 +188,7 @@ void UpdateFlyoutHeader()
UpdateFlyoutHeaderBehavior();
}

void UpdateFlyoutFooter()
protected virtual void UpdateFlyoutFooter()
{
if (_footerView != null)
{
Expand All @@ -201,14 +205,17 @@ void UpdateFlyoutFooter()

_footerView = new ShellViewRenderer(_shellContext.AndroidContext, footer);


_footerView.NativeView.LayoutParameters = new CoordinatorLayout.LayoutParams(LP.MatchParent, LP.WrapContent)
{
Gravity = (int)(GravityFlags.Bottom | GravityFlags.End)
};

_footerView.LayoutView(_shellContext.AndroidContext.FromPixels(_rootView.LayoutParameters.Width), -1);
_footerView.LayoutView(_shellContext.AndroidContext.FromPixels(_rootView.LayoutParameters.Width), double.PositiveInfinity);
_rootView.AddView(_footerView.NativeView);
if(_recycler?.LayoutParameters is CoordinatorLayout.LayoutParams cl)
{
cl.BottomMargin = (int)_shellContext.AndroidContext.ToPixels(_footerView.View.Height);
}
}

void UpdateVerticalScrollMode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ void SetupMenu()
SetupMenu(menu, _bottomView.MaxItemCount, ShellItem);
}

void UpdateTabBarVisibility()
protected virtual void UpdateTabBarVisibility()
{
if (DisplayedPage == null)
return;
Expand Down
60 changes: 38 additions & 22 deletions Xamarin.Forms.Platform.Android/Renderers/ShellViewRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace Xamarin.Forms.Platform.Android
// This is used to monitor an xplat View and apply layout changes
internal class ShellViewRenderer
{
IVisualElementRenderer _renderer;
public IVisualElementRenderer Renderer { get; private set; }
View _view;
WeakReference<Context> _context;
private double _width;
private double _height;
public double Width { get; private set; }
public double Height { get; private set; }

public ShellViewRenderer(Context context, View view)
{
Expand All @@ -36,37 +36,49 @@ public View View
public void TearDown()
{
View = null;
_renderer?.Dispose();
_renderer = null;
Renderer?.Dispose();
Renderer = null;
_view = null;
_context = null;
}

public void LayoutView(double width, double height)
public void LayoutView(double width, double height, double? maxWidth = null, double? maxHeight = null)
{
_width = width;
_height = height;
if (width == -1)
width = double.PositiveInfinity;

if (height == -1)
height = double.PositiveInfinity;

Width = width;
Height = height;
Context context;

if (_renderer == null || !(_context.TryGetTarget(out context)) || !_renderer.View.IsAlive())
if (Renderer == null || !(_context.TryGetTarget(out context)) || !Renderer.View.IsAlive())
return;

if (View == null)
{
var empty = MeasureSpecFactory.GetSize(0);
_renderer.View.Measure(empty, empty);
Renderer.View.Measure(empty, empty);
return;
}

var request = View.Measure(width, height, MeasureFlags.None);

var layoutParams = NativeView.LayoutParameters;
if (height == -1)
if (double.IsInfinity(height))
height = request.Request.Height;

if (width == -1)
if (double.IsInfinity(width))
width = request.Request.Width;

if (height > maxHeight)
height = maxHeight.Value;

if (width > maxWidth)
width = maxWidth.Value;

if (layoutParams.Width != LP.MatchParent)
layoutParams.Width = (int)context.ToPixels(width);

Expand All @@ -75,22 +87,22 @@ public void LayoutView(double width, double height)

NativeView.LayoutParameters = layoutParams;
View.Layout(new Rectangle(0, 0, width, height));
_renderer.UpdateLayout();
Renderer.UpdateLayout();
}

public void OnViewSet(View view)
public virtual void OnViewSet(View view)
{
if (View != null)
View.SizeChanged -= OnViewSizeChanged;

if (View is VisualElement oldView)
oldView.MeasureInvalidated -= OnViewSizeChanged;

if (_renderer != null)
if (Renderer != null)
{
_renderer.View.RemoveFromParent();
_renderer.Dispose();
_renderer = null;
Renderer.View.RemoveFromParent();
Renderer.Dispose();
Renderer = null;
}

_view = view;
Expand All @@ -101,19 +113,23 @@ public void OnViewSet(View view)
if (!(_context.TryGetTarget(out context)))
return;

_renderer = Platform.CreateRenderer(view, context);
Platform.SetRenderer(view, _renderer);
NativeView = _renderer.View;
Renderer = Platform.CreateRenderer(view, context);
Platform.SetRenderer(view, Renderer);
NativeView = Renderer.View;

if (View is VisualElement ve)
ve.MeasureInvalidated += OnViewSizeChanged;
else
View.SizeChanged += OnViewSizeChanged;
}
else
{
NativeView = null;
}
}

void OnViewSizeChanged(object sender, EventArgs e) =>
LayoutView(_width, _height);
LayoutView(Width, Height);

public AView NativeView
{
Expand Down

0 comments on commit 298e62a

Please sign in to comment.