lukhol
lukhol

Reputation: 388

Xamarin.forms animation

I would like to get gps position(Latitude and Longitude) in my Xamarin.Forms application. I am using Geolocator plugin and it takes minimum 5 seconds to get gps location. During this time i would like to create animation of loading. I made it but i can't stop animation. Efect of code below is there -> https://www.youtube.com/watch?v=MBf_VzaqkOQ&feature=youtu.be.

async void Button_Clicked(object sender, EventArgs e)
        {
            Plugin.Geolocator.Abstractions.Position position = new Plugin.Geolocator.Abstractions.Position();

            if(!locationProvider.IsGpsAvailable()){
                //...
            }
            else
            {
                try
                {
                    btnGetLocation.IsEnabled = false;
                    settingsLayout.IsVisible = true;
                    labelLatitude.Text = string.Empty;
                    labelLongitude.Text = string.Empty;

                    var locator = CrossGeolocator.Current;
                    locator.DesiredAccuracy = 0.5;

                    CancellationTokenSource cancellationTokenSoruce = new CancellationTokenSource();
                    CancellationToken ct = cancellationTokenSoruce.Token;

                    image1.Scale = 0;
                    image2.Scale = 0;
                    image3.Scale = 0;

                    Task.Run(async () =>
                    {
                        for (int i = 0; i < 20; i++)
                        {
                            await image1.ScaleTo(1, 400, Easing.Linear);
                            await image1.ScaleTo(0, 400, Easing.Linear);
                            await image1.TranslateTo(image1.TranslationX, image1.TranslationY, 600, Easing.Linear);
                        }
                    }, ct);

                    Task.Run(async () =>
                    {
                        for (int i = 0; i < 20; i++)
                        {
                            await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 200, Easing.Linear);
                            await image2.ScaleTo(1, 400, Easing.Linear);
                            await image2.ScaleTo(0, 400, Easing.Linear);
                            await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 400, Easing.Linear);
                        }
                    }, ct);

                    Task.Run(async () =>
                    {
                        for (int i = 0; i < 20; i++)
                        {
                            await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 400, Easing.Linear);
                            await image3.ScaleTo(1, 400, Easing.Linear);
                            await image3.ScaleTo(0, 400, Easing.Linear);
                            await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 200, Easing.Linear);
                        }
                    }, ct);

                    position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
                    cancellationTokenSoruce.Cancel();
                    ViewExtensions.CancelAnimations(image1);
                    ViewExtensions.CancelAnimations(image2);
                    ViewExtensions.CancelAnimations(image3);
                }
                catch
                {
                }

                image1.Scale = 0;
                image2.Scale = 0;
                image3.Scale = 0;

                labelLatitude.Text = position.Latitude.ToString();
                labelLongitude.Text = position.Longitude.ToString();

                //settingsLayout.IsVisible = false;
                btnGetLocation.IsEnabled = true;
            }
        }

ViewExtensions.CancelAnimations(image); should stop animation but it does not work and cancelation token should stop method in task. What is wrong in this code?

Edit: I forget about xaml file:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamarinFormsOne.Pages.GPSOwnTestPage"
             BackgroundColor="{StaticResource PageBackgroundColor}">
    <ContentPage.Content>
        <StackLayout>
            <Button x:Name="btnGetLocation"
                    Text="Get GPS Avability"
                    Clicked="Button_Clicked"/>
            <Label x:Name="labelLatitude"
                   HorizontalOptions="CenterAndExpand"
                   VerticalOptions="CenterAndExpand"
                   TextColor="White"/>
            <Label x:Name="labelLongitude"
                   HorizontalOptions="CenterAndExpand"
                   VerticalOptions="CenterAndExpand"
                   TextColor="White"/>
            <StackLayout Orientation="Horizontal" x:Name="settingsLayout">
                <Grid WidthRequest="120"/>
                <Image x:Name="image1"
                      Source="settingsIcon.png"
                      HorizontalOptions="EndAndExpand"
                      VerticalOptions="EndAndExpand"/>
                <Image x:Name="image2"
                      Source="settingsIcon.png"
                      HorizontalOptions="CenterAndExpand"
                      VerticalOptions="EndAndExpand"/>
                <Image x:Name="image3"
                      Source="settingsIcon.png"
                      HorizontalOptions="StartAndExpand"
                      VerticalOptions="EndAndExpand"/>
                <Grid WidthRequest="120"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Upvotes: 0

Views: 977

Answers (2)

lukhol
lukhol

Reputation: 388

I resolved my problem like this, maybe it will be helpful for someone:

async void Button_Clicked(object sender, EventArgs e)
        {
            Plugin.Geolocator.Abstractions.Position position = new Plugin.Geolocator.Abstractions.Position();

            if(!locationProvider.IsGpsAvailable()){
                //
            }
            else
            {
                CancellationTokenSource cancellationTokenSoruce = new CancellationTokenSource();
                CancellationToken ct = cancellationTokenSoruce.Token;

                image1.Scale = 0;
                image2.Scale = 0;
                image3.Scale = 0;

                labelLatitude.Text = string.Empty;
                labelLongitude.Text = string.Empty;

                Content = acquiringLocationLayoutHandler;

                try
                {
                    var locator = CrossGeolocator.Current;
                    locator.DesiredAccuracy = 0.5;

                    var t1 = Task.Run(async () =>
                    {
                        while(!ct.IsCancellationRequested)
                        {
                            await image1.ScaleTo(1, 400, Easing.Linear);
                            await image1.ScaleTo(0, 400, Easing.Linear);
                            await image1.TranslateTo(image1.TranslationX, image1.TranslationY, 600, Easing.Linear);

                            if (ct.IsCancellationRequested)
                            {
                                ViewExtensions.CancelAnimations(image1);
                            }
                        }
                    }, ct);

                    var t2 = Task.Run(async () =>
                    {
                        while (!ct.IsCancellationRequested)
                        {
                            await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 200, Easing.Linear);
                            await image2.ScaleTo(1, 400, Easing.Linear);
                            await image2.ScaleTo(0, 400, Easing.Linear);
                            await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 400, Easing.Linear);

                            if (ct.IsCancellationRequested)
                            {
                                ViewExtensions.CancelAnimations(image2);
                            }
                        }
                    }, ct);

                    var t3 = Task.Run(async () =>
                    {
                        while (!ct.IsCancellationRequested)
                        {
                            await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 400, Easing.Linear);
                            await image3.ScaleTo(1, 400, Easing.Linear);
                            await image3.ScaleTo(0, 400, Easing.Linear);
                            await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 200, Easing.Linear);

                            if (ct.IsCancellationRequested)
                            {
                                ViewExtensions.CancelAnimations(image3);
                            }
                        }
                    }, ct);

                    position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
                }
                catch(Exception ee)
                {
                    Debug.WriteLine(ee.Message);
                }
                finally
                {
                    cancellationTokenSoruce.Cancel();   
                }

                labelLatitude.Text = position.Latitude.ToString();
                labelLongitude.Text = position.Longitude.ToString();

                Content = mainLayoutHandler;
            }

Upvotes: 0

Yuri S
Yuri S

Reputation: 5370

Here is what you can do

    async void Button_Clicked(object sender, EventArgs e)
    {
        //Plugin.Geolocator.Abstractions.Position position = new Plugin.Geolocator.Abstractions.Position();

        //if (!locationProvider.IsGpsAvailable())
        //{
        //    //...
        //}
        //else
        //{
        try
        {
            btnGetLocation.IsEnabled = false;
            settingsLayout.IsVisible = true;
            labelLatitude.Text = string.Empty;
            labelLongitude.Text = string.Empty;

            //var locator = CrossGeolocator.Current;
            //locator.DesiredAccuracy = 0.5;

            CancellationTokenSource cancellationTokenSoruce = new CancellationTokenSource();
            CancellationToken ct = cancellationTokenSoruce.Token;

            image1.Scale = 0;
            image2.Scale = 0;
            image3.Scale = 0;

            Task[] tasks = new Task[3];
            tasks[0] = Task.Run(async () =>
            {
                while (!ct.IsCancellationRequested)
                {
                    await image1.ScaleTo(1, 400, Easing.Linear);
                    await image1.ScaleTo(0, 400, Easing.Linear);
                    await image1.TranslateTo(image1.TranslationX, image1.TranslationY, 600, Easing.Linear);
                }
            });

            tasks[1] = Task.Run(async () =>
            {
                while (!ct.IsCancellationRequested)
                {
                    await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 200, Easing.Linear);
                    await image2.ScaleTo(1, 400, Easing.Linear);
                    await image2.ScaleTo(0, 400, Easing.Linear);
                    await image2.TranslateTo(image2.TranslationX, image2.TranslationY, 400, Easing.Linear);
                }
            });

            tasks[2] = Task.Run(async () =>
            {
                while (!ct.IsCancellationRequested)
                {
                    await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 400, Easing.Linear);
                    await image3.ScaleTo(1, 400, Easing.Linear);
                    await image3.ScaleTo(0, 400, Easing.Linear);
                    await image3.TranslateTo(image3.TranslationX, image3.TranslationY, 200, Easing.Linear);
                }
            });

            //position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
            await Task.Delay(10000); //simulated GetPositionAsync
            cancellationTokenSoruce.Cancel();
            await Task.WhenAll(tasks);

            //no need in CancelAnimations, it is done when you exited the Task
            //ViewExtensions.CancelAnimations(image1);
            //ViewExtensions.CancelAnimations(image2);
            //ViewExtensions.CancelAnimations(image3);

        }
        catch
        {
        }

        image1.Scale = 0;
        image2.Scale = 0;
        image3.Scale = 0;

        //labelLatitude.Text = position.Latitude.ToString();
        //labelLongitude.Text = position.Longitude.ToString();

        //settingsLayout.IsVisible = false;
        btnGetLocation.IsEnabled = true;
    }
    //}

Upvotes: 0

Related Questions