How can I make label to smoothly increase height ?

ZoomZoom Member ✭✭
edited August 22 in Xamarin.Forms

I want to make label or any other element to smoothly increase height or width. But I can't find any examples how to make something like this. Can you advice me how to make this? I'm thinking about changing absolute coordinates of label in cycle in async thread,but I can't manage how to access label from another thread(none of solutions with invoke from this forum worked for me)

Best Answer

Answers

  • JohnHardmanJohnHardman GBUniversity mod

    @Zoom said:
    I want to make label or any other element to smoothly increase height or width. But I can't find any examples how to make something like this. Can you advice me how to make this? I'm thinking about changing absolute coordinates of label in cycle in async thread,but I can't manage how to access label from another thread(none of solutions with invoke from this forum worked for me)

    Use ScaleTo. See https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.viewextensions.scaleto?view=xamarin-forms

    Do not attempt to do animation from a non-UI thread.

  • ZoomZoom Member ✭✭
    edited August 22

    @JohnHardman said:

    @Zoom said:
    I want to make label or any other element to smoothly increase height or width. But I can't find any examples how to make something like this. Can you advice me how to make this? I'm thinking about changing absolute coordinates of label in cycle in async thread,but I can't manage how to access label from another thread(none of solutions with invoke from this forum worked for me)

    Use ScaleTo. See

    Do not attempt to do animation from a non-UI thread.

    But ScaleTo increases both X and Y, and I need only Y. And ScaleY doesn't have any animation. Am I missing something?

  • LandLuLandLu Member, Xamarin Team Xamurai

    You can use Timer to implement the animation by yourself:

    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = 250;
    timer.Elapsed += (s, args) =>
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            MyLabel.HeightRequest += 1;
            if (MyLabel.HeightRequest == 100)
            {
                timer.Stop();
                timer.Dispose();
            }
        });
    };
    timer.Start();
    

    Adjust the interval and increasing constant as you want.

  • ZoomZoom Member ✭✭
    edited August 23

    @LandLu said:
    You can use Timer to implement the animation by yourself:

    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = 250;
    timer.Elapsed += (s, args) =>
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            MyLabel.HeightRequest += 1;
            if (MyLabel.HeightRequest == 100)
            {
                timer.Stop();
                timer.Dispose();
            }
        });
    };
    timer.Start();
    

    Adjust the interval and increasing constant as you want.

    Thanks for your help! Height increases correct, but without any animation. If I'm not mistaken, that's why

    HeightRequest does not immediately change the Bounds of a VisualElement, however setting the HeightRequest will
    change the result of calls to GetSizeRequest, which will in turn modify the final size the element receives during a layout
    cycle.

    Is there any way to manually refresh page after height change?

  • LandLuLandLu Member, Xamarin Team Xamurai

    @Zoom Plase try my code. I placed the height request changed in a timer. It means every 0.25 second the height will increase 1. You can set a smaller value so that it will display an animation.

  • JohnHardmanJohnHardman GBUniversity mod

    @Zoom said:
    But ScaleTo increases both X and Y, and I need only Y. And ScaleY doesn't have any animation. Am I missing something?

    If you look at the Xamarin.Forms source (it is open source and available from GitHub), you can find the source of ScaleTo in Xamarin.Forms.Core\ViewExtensions.cs

    ScaleTo looks like this:

        public static Task<bool> ScaleTo(this VisualElement view, double scale, uint length = 250, Easing easing = null)
        {
            if (view == null)
                throw new ArgumentNullException(nameof(view));
    
            return AnimateTo(view, view.Scale, scale, nameof(ScaleTo), (v, value) => v.Scale = value, length, easing);
        }
    

    Implementing a ScaleYTo should be little more than replacing each instance of Scale by ScaleY.

Sign In or Register to comment.