Absolute layout "without fill, space"

AleKutekAleKutek USMember ✭✭

Hello,
is possible to position control with absolute layout without taking any space? Something like "position: absolute" in CSS.

The situation is that, I need to create tooltip (label) above slider which will show current value and will be shown only if user changes it's value.
But when I show tooltip, then It takes space instead of overlaping above other controls.
Is It possible or anybody has any idea?
Thanks.

Answers

  • AsurAsur USMember ✭✭✭

    Can you post the code? IF you are using absolute layout correctly it should be possible. You will need a popup control for tooltip. Maybe try Acr.UserDialogues for the same. I personally use syncfusion but go through the licensing once.

  • AleKutekAleKutek USMember ✭✭

    xaml file:

    <StackLayout>
            <AbsoluteLayout x:Name="AbsoluteLayoutLabel">
                <Label x:Name="Label" Text="tooltip test"></Label>
            </AbsoluteLayout>
            <Slider RelativeLayout.WidthConstraint=
                    "{ConstraintExpression Type=RelativeToParent,
                                    Property=Width,
                                    Factor=1}"
                    HorizontalOptions="FillAndExpand" ValueChanged="Slider_OnValueChanged" x:Name="Slider" Maximum="100" Minimum="0"></Slider>
    </StackLayout>
    
  • jezhjezh Member, Xamarin Team Xamurai

    What do you meaning by saying Absolute layout "without fill, space ? Could you please post more detail about this ,eg. effect image ?

  • AleKutekAleKutek USMember ✭✭

    I recorded a video:
    https://tinytake.s3.amazonaws.com/pulse/twinity/attachments/10127845/TinyTake14-03-2019-09-32-57.mp4

    I solved one problem:
    My problem was when I moved the item on Y I was setting bounds of the "Tooltip", which caused expanding of the absolute layout.
    I'm setting those bounds directly to absoluteLayout above the tooltip now and it works as I expected.

    But there's one more problem still:
    I need somehow to overlap navigation bar with the tooltip.

    Here's my xaml:

        <StackLayout>
                <AbsoluteLayout BackgroundColor="Blue" x:Name="AbsoluteLayoutTooltip">
                        <Label BackgroundColor="Gold" x:Name="Tooltip" Text="Test tes test"></Label>
                </AbsoluteLayout>
                    <StackLayout HorizontalOptions="FillAndExpand">
                            <Slider MinimumTrackColor="Aqua" ValueChanged="Slider_OnValueChanged" x:Name="Slider" Maximum="100" Minimum="0"></Slider>
                            <Slider MinimumTrackColor="Navy" ValueChanged="Height_OnValueChanged" x:Name="Height" Maximum="200" Minimum="-100"></Slider>
                            <Label x:Name="Label2"></Label>
                    </StackLayout>
        </StackLayout>
    
  • jezhjezh Member, Xamarin Team Xamurai

    I am so sorry so late to reply . Have you got the solution?

  • AleKutekAleKutek USMember ✭✭

    I have the solution.
    I used canvas drawing in a custom renderer for slider.
    I have implemented this only for android. For iOS I will implement this in the future, but I hope it will be almost the same.
    The code is little messy, but it might help someone (the result is the tooltip above slider how the spotify has).

        private void DrawToolTip(Canvas canvas)
        {
            var textPaint = new Paint(PaintFlags.AntiAlias);
            var text = Element.Value.ToString(CultureInfo.CurrentCulture);
    
            SliderCustom sliderCustom = Element as SliderCustom; // I made custom slider only for custom text through action call, you can ommit lines with custom slider..
    
            if (sliderCustom.TooltipText != null)
            {
                text = sliderCustom.TooltipText.Invoke(Element.Value);
            }
    
            textPaint.Color = Color.Rgb(254, 254, 254);
    
            textPaint.TextSize = 20;
    
            float measureText = textPaint.MeasureText(text);
            float boxWidth = measureText;
    
            float minWidth = 50;
    
            if (measureText < minWidth)
            {
                boxWidth = minWidth;
            }
    
            int paddingLeftRight = 16;
            int paddingTopBottom = 8;
    
            var boundsLeft = Control.Thumb.Bounds.Left + Control.PaddingLeft - (boxWidth / 2);
            var boundsTop = Control.Thumb.Bounds.Top - 40;
    
            var rectPaint = new Paint(PaintFlags.AntiAlias);
    
            rectPaint.AntiAlias = true;
    
            Color blackColor = Color.Rgb(37, 37, 37);
            rectPaint.Color = blackColor;
    
            int round = 6;
    
            float bottom = boundsTop + textPaint.TextSize + paddingTopBottom;
            var top = boundsTop - paddingTopBottom;
            var left = boundsLeft - paddingLeftRight;
            var right = boundsLeft + boxWidth + paddingLeftRight;
            canvas.DrawRoundRect(left, top, right, bottom, round, round, rectPaint);
            canvas.DrawText(text, boundsLeft, bottom - (textPaint.TextSize / 2), textPaint);
    
            Paint trianglePaint = new Paint();
            trianglePaint.Color = blackColor;
    
            Path path = new Path();
    
            trianglePaint.StrokeWidth = 0;
            trianglePaint.SetStyle(Paint.Style.FillAndStroke);
    
            float triangleWidth = 15;
            float triangleHeight = 6;
    
            float triangleBottomPosition = bottom;
    
            trianglePaint.AntiAlias = true;
    
            float triangleLeftPosition = left + (right - left) / 2 - (triangleWidth / 2);
    
            path.MoveTo(triangleLeftPosition, triangleBottomPosition);
            path.LineTo(triangleLeftPosition + triangleWidth / 2, triangleBottomPosition + triangleHeight);
            path.LineTo(triangleLeftPosition + triangleWidth, triangleBottomPosition);
            path.LineTo(triangleLeftPosition, triangleBottomPosition);
            path.Close();
    
            canvas.DrawPath(path, trianglePaint);
        }
    
Sign In or Register to comment.