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; }
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); } }
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); } }
public void UpdateLayout() { Performance.Start(); VisualElement view = _renderer.Element; AView aview = _renderer.ViewGroup; var x = (int)_context.ToPixels(view.X); var y = (int)_context.ToPixels(view.Y); var width = (int)_context.ToPixels(view.Width); var height = (int)_context.ToPixels(view.Height); var formsViewGroup = aview as FormsViewGroup; if (formsViewGroup == null) { Performance.Start("Measure"); aview.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); Performance.Stop("Measure"); Performance.Start("Layout"); aview.Layout(x, y, x + width, y + height); Performance.Stop("Layout"); } else { Performance.Start("MeasureAndLayout"); formsViewGroup.MeasureAndLayout(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.Exactly), x, y, x + width, y + height); Performance.Stop("MeasureAndLayout"); } Performance.Stop(); //On Width or Height changes, the anchors needs to be updated UpdateAnchorX(); UpdateAnchorY(); }
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)Forms.SdkInt >= 18) { UpdateClipToBounds(); } Performance.Stop(reference); //On Width or Height changes, the anchors needs to be updated UpdateAnchorX(); UpdateAnchorY(); }
public void UpdateLayout() { var reference = Guid.NewGuid().ToString(); Performance.Start(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"); } Performance.Stop(reference); //On Width or Height changes, the anchors needs to be updated UpdateAnchorX(); UpdateAnchorY(); }
public void LayoutView(double x, double y, double width, double height, double?maxWidth = null, double?maxHeight = null) { if (width == -1) { width = double.PositiveInfinity; } if (height == -1) { height = double.PositiveInfinity; } Width = width; Height = height; MaxWidth = maxWidth; MaxHeight = maxHeight; X = x; Y = y; Context context; if (Renderer == null || !(_context.TryGetTarget(out context)) || !Renderer.View.IsAlive()) { return; } if (View == null) { var empty = MeasureSpecFactory.GetSize(0); Renderer.View.Measure(empty, empty); return; } var request = View.Measure(width, height, MeasureFlags.None); var layoutParams = NativeView.LayoutParameters; if (double.IsInfinity(height)) { height = request.Request.Height; } 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); } if (layoutParams.Height != LP.MatchParent) { layoutParams.Height = (int)context.ToPixels(height); } NativeView.LayoutParameters = layoutParams; View.Layout(new Rectangle(x, y, width, height)); Renderer.UpdateLayout(); }