void OnElementSizeChanged(object sender, EventArgs e) { Profile.FrameBegin(); Profile.FramePartition("ToPixels"); int width = (int)AndroidContext.ToPixels(Element.Width); int height = (int)AndroidContext.ToPixels(Element.Height); Profile.FramePartition("Measure"); _flyoutRenderer.AndroidView.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); Profile.FramePartition("Layout"); _flyoutRenderer.AndroidView.Layout(0, 0, width, height); Profile.FrameEnd(); }
public void UpdateLayout() { Performance.Start(out string reference); VisualElement view = _renderer.Element; AView aview = _renderer.View; var headlessOffset = CompressedLayout.GetHeadlessOffset(view); var x = (int)_context.ToPixels(view.X + headlessOffset.X); var y = (int)_context.ToPixels(view.Y + headlessOffset.Y); var width = Math.Max(0, (int)_context.ToPixels(view.Width)); var height = Math.Max(0, (int)_context.ToPixels(view.Height)); var formsViewGroup = aview as FormsViewGroup; if (formsViewGroup == null) { Performance.Start(reference, "Measure"); aview.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); Performance.Stop(reference, "Measure"); Performance.Start(reference, "Layout"); aview.Layout(x, y, x + width, y + height); Performance.Stop(reference, "Layout"); } else { Performance.Start(reference, "MeasureAndLayout"); formsViewGroup.MeasureAndLayout(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly), x, y, x + width, y + height); Performance.Stop(reference, "MeasureAndLayout"); } // If we're running sufficiently new Android, we have to make sure to update the ClipBounds to // match the new size of the ViewGroup if ((int)System.Maui.Maui.SdkInt >= 18) { UpdateClipToBounds(); } Performance.Stop(reference); //On Width or Height changes, the anchors needs to be updated UpdateAnchorX(); UpdateAnchorY(); }
protected override void OnLayout(bool changed, int left, int top, int right, int bottom) { var width = right - left; width -= (int)Context.ToPixels(25); var height = bottom - top; for (int i = 0; i < ChildCount; i++) { var child = GetChildAt(i); child.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); child.Layout(0, 0, width, height); } _textBlock.DropDownHorizontalOffset = -_textBlock.Left; _textBlock.DropDownVerticalOffset = -(int)System.Math.Ceiling(_cardView.Radius); _textBlock.DropDownWidth = width; }
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (_child?.Element == null) { SetMeasuredDimension(0, 0); return; } VisualElement element = _child.Element; Context ctx = Context; var width = (int)ctx.FromPixels(MeasureSpecFactory.GetSize(widthMeasureSpec)); SizeRequest request = element.Measure(width, double.PositiveInfinity, MeasureFlags.IncludeMargins); System.Maui.Layout.LayoutChildIntoBoundingRegion(element, new Rectangle(0, 0, width, request.Request.Height)); int widthSpec = MeasureSpecFactory.MakeMeasureSpec((int)ctx.ToPixels(width), MeasureSpecMode.Exactly); int heightSpec = MeasureSpecFactory.MakeMeasureSpec((int)ctx.ToPixels(request.Request.Height), MeasureSpecMode.Exactly); _child.View.Measure(widthMeasureSpec, heightMeasureSpec); SetMeasuredDimension(widthSpec, heightSpec); }
protected override void OnLayout(bool changed, int left, int top, int right, int bottom) { // If the scroll view has changed size because of soft keyboard dismissal // (while WindowSoftInputModeAdjust is set to Resize), then we may need to request a // layout of the ScrollViewContainer bool requestContainerLayout = bottom > _previousBottom; _previousBottom = bottom; _container?.Measure(MeasureSpecFactory.MakeMeasureSpec(right - left, MeasureSpecMode.Unspecified), MeasureSpecFactory.MakeMeasureSpec(bottom - top, MeasureSpecMode.Unspecified)); base.OnLayout(changed, left, top, right, bottom); if (_view.Content != null && _hScrollView != null) { _hScrollView.Layout(0, 0, right - left, Math.Max(bottom - top, (int)Context.ToPixels(_view.Content.Height))); } else if (_view.Content != null && requestContainerLayout) { _container?.RequestLayout(); } // if the target sdk >= 17 then setting the LayoutDirection on the scroll view natively takes care of the scroll if (!_checkedForRtlScroll && _hScrollView != null && Element is IVisualElementController controller && controller.EffectiveFlowDirection.IsRightToLeft()) { if (Context.TargetSdkVersion() < 17) { _hScrollView.ScrollX = _container.MeasuredWidth - _hScrollView.MeasuredWidth - _hScrollView.ScrollX; } else { Device.BeginInvokeOnMainThread(() => UpdateScrollPosition(_hScrollView.ScrollX, ScrollY)); } } _checkedForRtlScroll = true; }
void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e) { if (!_isAttached) { _pendingScrollTo = e; return; } Cell cell; int position; var scrollArgs = (ITemplatedItemsListScrollToRequestedEventArgs)e; var templatedItems = TemplatedItemsView.TemplatedItems; if (Element.IsGroupingEnabled) { var results = templatedItems.GetGroupAndIndexOfItem(scrollArgs.Group, scrollArgs.Item); if (results.Item1 == -1 || results.Item2 == -1) { return; } var group = templatedItems.GetGroup(results.Item1); cell = group[results.Item2]; position = templatedItems.GetGlobalIndexForGroup(group) + results.Item2 + 1; } else { position = templatedItems.GetGlobalIndexOfItem(scrollArgs.Item); if (position == -1) { return; } cell = templatedItems[position]; } //Android offsets position of cells when using header int realPositionWithHeader = position + 1; if (e.Position == ScrollToPosition.MakeVisible) { if (e.ShouldAnimate) { Control.SmoothScrollToPosition(realPositionWithHeader); } else { Control.SetSelection(realPositionWithHeader); } return; } int height = Control.Height; var cellHeight = (int)cell.RenderHeight; if (cellHeight == -1) { int first = Control.FirstVisiblePosition; if (first <= position && position <= Control.LastVisiblePosition) { cellHeight = Control.GetChildAt(position - first).Height; } else { AView view = _adapter.GetView(position, null, null); view.Measure(MeasureSpecFactory.MakeMeasureSpec(Control.Width, MeasureSpecMode.AtMost), MeasureSpecFactory.MakeMeasureSpec(0, MeasureSpecMode.Unspecified)); cellHeight = view.MeasuredHeight; } } var y = 0; if (e.Position == ScrollToPosition.Center) { y = height / 2 - cellHeight / 2; } else if (e.Position == ScrollToPosition.End) { y = height - cellHeight; } if (e.ShouldAnimate) { Control.SmoothScrollToPositionFromTop(realPositionWithHeader, y); } else { Control.SetSelectionFromTop(realPositionWithHeader, y); } }
protected override void OnLayout(bool changed, int l, int t, int r, int b) { base.OnLayout(changed, l, t, r, b); if (_viewPager != null) { _viewPager.Measure(MeasureSpecFactory.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly)); _viewPager.Layout(0, 0, r - l, b - t); } }