示例#1
0
        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));


            if (aview is FormsViewGroup formsViewGroup)
            {
                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");
            }
            else if ((aview is LayoutViewGroup || aview is ContentViewGroup || aview is CoordinatorLayout || aview is FragmentContainerView) && width == 0 && height == 0)
            {
                // Nothing to do here; just chill.
            }
            else
            {
                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");
            }

            // We have to make sure to update the ClipBounds to match the new size of the ViewGroup
            UpdateClipToBounds();
            UpdateClip();

            Performance.Stop(reference);

            //On Width or Height changes, the anchors needs to be updated
            UpdateAnchorX();
            UpdateAnchorY();
        }
示例#3
0
        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;
        }
示例#4
0
        public static SizeRequest GetNativeSize(
            IVisualElementRenderer visualElementRenderer,
            double widthConstraint,
            double heightConstraint)
        {
            var context = visualElementRenderer.View.Context;

            // negative numbers have special meanings to android they don't to us
            widthConstraint  = widthConstraint <= -1 ? double.PositiveInfinity : context.ToPixels(widthConstraint);
            heightConstraint = heightConstraint <= -1 ? double.PositiveInfinity : context.ToPixels(heightConstraint);

            bool widthConstrained  = !double.IsPositiveInfinity(widthConstraint);
            bool heightConstrained = !double.IsPositiveInfinity(heightConstraint);

            int widthMeasureSpec = widthConstrained
                                                        ? MeasureSpecFactory.MakeMeasureSpec((int)widthConstraint, MeasureSpecMode.AtMost)
                                                        : MeasureSpecFactory.MakeMeasureSpec(0, MeasureSpecMode.Unspecified);

            int heightMeasureSpec = heightConstrained
                                                         ? MeasureSpecFactory.MakeMeasureSpec((int)heightConstraint, MeasureSpecMode.AtMost)
                                                         : MeasureSpecFactory.MakeMeasureSpec(0, MeasureSpecMode.Unspecified);

            SizeRequest rawResult = visualElementRenderer.GetDesiredSize(widthMeasureSpec, heightMeasureSpec);

            if (rawResult.Minimum == Size.Zero)
            {
                rawResult.Minimum = rawResult.Request;
            }
            var result = new SizeRequest(new Size(context.FromPixels(rawResult.Request.Width), context.FromPixels(rawResult.Request.Height)),
                                         new Size(context.FromPixels(rawResult.Minimum.Width), context.FromPixels(rawResult.Minimum.Height)));

            if ((widthConstrained && result.Request.Width < widthConstraint) ||
                (heightConstrained && result.Request.Height < heightConstraint))
            {
                // Do a final exact measurement in case the native control needs to fill the container
                (visualElementRenderer as IViewRenderer)?.MeasureExactly();
            }

            return(result);
        }
示例#5
0
            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);

                Microsoft.Maui.Controls.Compatibility.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);
            }
示例#6
0
        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;
        }
示例#7
0
        void IPlatformLayout.OnLayout(bool changed, int l, int t, int r, int b)
        {
            if (Page == null)
            {
                return;
            }

            if (changed)
            {
                LayoutRootPage(Page, r - l, b - t);
            }

            GetRenderer(Page)?.UpdateLayout();

            for (var i = 0; i < _renderer.ChildCount; i++)
            {
                AView child = _renderer.GetChildAt(i);
                if (child is ModalContainer)
                {
                    child.Measure(MeasureSpecFactory.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(t - b, MeasureSpecMode.Exactly));
                    child.Layout(l, t, r, b);
                }
            }
        }
示例#8
0
        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 Controls.Android.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();
            }

            UpdateClip();

            Performance.Stop(reference);

            //On Width or Height changes, the anchors needs to be updated
            UpdateAnchorX();
            UpdateAnchorY();
        }
示例#9
0
        void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
        {
            if (!_isAttached)
            {
                _pendingScrollTo = e;
                return;
            }

            Cell cell;
            int  scrollPosition;
            var  scrollArgs = (ITemplatedItemsListScrollToRequestedEventArgs)e;

            var templatedItems = TemplatedItemsView.TemplatedItems;

            if (Element.IsGroupingEnabled)
            {
                var results      = templatedItems.GetGroupAndIndexOfItem(scrollArgs.Group, scrollArgs.Item);
                int indexOfGroup = results.Item1;
                int indexOfItem  = results.Item2;

                if (indexOfGroup == -1)
                {
                    return;
                }

                int itemIndex = indexOfItem == -1 ? 0 : indexOfItem;

                var group = templatedItems.GetGroup(indexOfGroup);
                if (group.Count == 0)
                {
                    cell = group.HeaderContent;
                }
                else
                {
                    cell = group[itemIndex];
                }

                //Increment Scroll Position by 1 when Grouping is enabled. Android offsets position of cells when using header.
                scrollPosition = templatedItems.GetGlobalIndexForGroup(group) + itemIndex + 1;
            }
            else
            {
                scrollPosition = templatedItems.GetGlobalIndexOfItem(scrollArgs.Item);
                if (scrollPosition == -1)
                {
                    return;
                }

                cell = templatedItems[scrollPosition];
            }

            //Android offsets position of cells when using header
            int realPositionWithHeader = scrollPosition + 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 <= scrollPosition && scrollPosition <= Control.LastVisiblePosition)
                {
                    cellHeight = Control.GetChildAt(scrollPosition - first).Height;
                }
                else
                {
                    AView view = _adapter.GetView(scrollPosition, 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);
            }
        }