Busy animation won't display when setting IsBusy = false

8 posts, 0 answers
  1. Bill
    Bill avatar
    33 posts
    Member since:
    Nov 2017

    Posted 04 Dec 2017 Link to this post

    I am having trouble displaying the BusyIndicator in my project. Here's my XAML:

    <?xml version="1.0" encoding="UTF-8"?>
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:telerikListView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls"
                 xmlns:telerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
                 xmlns:iconize="clr-namespace:FormsPlugin.Iconize;assembly=FormsPlugin.Iconize"
                 xmlns:upTimeMobile="clr-namespace:UpTimeMobile;assembly=UpTimeMobile.Android"
                 xmlns:lc="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"
                 xmlns:lb="clr-namespace:XLabs.Forms.Behaviors;assembly=XLabs.Forms"
                 xmlns:lcon="clr-namespace:XLabs.Forms.Converter;assembly=XLabs.Forms"
                 xmlns:lp="clr-namespace:XLabs.Forms.Pages;assembly=XLabs.Forms"
                 xmlns:telerikBusyIndicator="clr-namespace:Telerik.XamarinForms.Primitives;assembly=Telerik.XamarinForms.Primitives"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 x:Class="MyApp.Views.Details">
        <telerikBusyIndicator:RadBusyIndicator x:Name="BusyIndicator"
                                               AnimationType="Animation6"
                                               AnimationContentColor="DodgerBlue"
                                               AnimationContentHeightRequest="100"
                                               AnimationContentWidthRequest="100"
                                               IsBusy="True">
            <telerikBusyIndicator:RadBusyIndicator.Content>
             
                <!-- Radlist goes here... -->
                 
            </telerikBusyIndicator:RadBusyIndicator.Content>
        </telerikBusyIndicator:RadBusyIndicator>
    </ContentPage>

     

    This works, and the busy animation appears on the screen. However, if I try to set the indicator to false, the busy indicator doesn't appear at all when the content page is loading. Here's my code:

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Details : ContentPage
    {
        public Details(Guid Id, string name)
        {
            InitializeComponent();
             
            BusyIndicator.IsBusy = true;
            DoLoad();
            BusyIndicator.IsBusy = false;
        }
         
        private void DoLoad()
        {
            // do data load here...
            ListViewDetails.ItemsSource = results;
        }
    }

     

    I also tried using async like this (but still doesn't work):

    private async void DoLoad()
    {
        await Task.Run(() =>
        {
            // do data load here...
            ListViewDetails.ItemsSource = results;
        });
    }

     

    My Android project min version is 6.0 (23), target is 6.0 (23), compiled using 8.0. I'm using Telerik UI for Xamarin R3 2017 and I also have SkiaSharp.Views.Forms 1.59.2 installed.

  2. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1045 posts

    Posted 04 Dec 2017 Link to this post

    Hi Bill,

    The page constructor isn't an appropriate place to handling data-loading methods. Instead, use OnAppearing (which you can also mark async, this is not possible for constructors).

    For example:
    protected override async void OnAppearing()
    {
        base.OnAppearing();
     
        BusyIndicator.IsBusy = true;
     
        var result = await LoadDataAsync();
     
        ListViewDetails = result;
     
        BusyIndicator.IsBusy = true;
    }


    Even better, use a try-catch and hide the BusyIndicator in the finally clause:

    protected override async void OnAppearing()
    {
        base.OnAppearing();
     
        try
        {
            BusyIndicator.IsBusy = true;
     
            var result = await LoadDataAsync();
     
            ListViewDetails = result;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
        }
        finally
        {
            BusyIndicator.IsBusy = true;
        }
    }


    If this doesn't work for you, we'll need to investigate further. You can open a support ticket here and attach your code files so that we can replicate the problem for direct debugging.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1045 posts

    Posted 04 Dec 2017 Link to this post

    Hello Bill,

    Small correction in my last reply's code snippets; in the finally clause I left the IsBusy = true, that should be IsBusy=False. 

    Let me share the full code I used to test your report, this way you can see it in action outside of your application.


    ViewModel (with async Task for loading data):

    public class ViewModel
    {
        public ViewModel()
        {
        }
     
        public ObservableCollection<BookItemViewModel> Source { get; set; } = new ObservableCollection<BookItemViewModel>();
     
        public async Task LoadDataAsync()
        {
            var result = await GetItemsAsync();
     
            foreach (var item in result)
            {
                Source.Add(item);
            }
        }
     
        private Task<ObservableCollection<BookItemViewModel>> GetItemsAsync()
        {
            return Task.Run(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(3));
     
                return new ObservableCollection<BookItemViewModel>
                {
                    new BookItemViewModel {Title = "The Fault in Our Stars ", Author = "John Green", IsInStock = true},
                    new BookItemViewModel {Title = "Divergent", Author = "Veronica Roth"},
                    new BookItemViewModel {Title = "Gone Girl", Author = "Gillian Flynn", IsInStock = true},
                    new BookItemViewModel {Title = "Clockwork Angel", Author = "Cassandra Clare"},
                    new BookItemViewModel {Title = "The Martian", Author = "Andy Weir"},
                    new BookItemViewModel {Title = "Ready Player One", Author = "Ernest Cline"},
                    new BookItemViewModel {Title = "The Lost Hero", Author = "Rick Riordan", IsInStock = true},
                    new BookItemViewModel {Title = "All the Light We Cannot See", Author = "Anthony Doerr"},
                    new BookItemViewModel {Title = "Cinder", Author = "Marissa Meyer"},
                    new BookItemViewModel {Title = "Me Before You", Author = "Jojo Moyes"},
                    new BookItemViewModel {Title = "The Night Circus", Author = "Erin Morgenstern"},
                };
     
            });
        }
    }


    XAML

    <ContentPage ... >
     
        <ContentPage.BindingContext>
            <viewModels:ViewModel x:Name="ViewModel"/>
        </ContentPage.BindingContext>
     
        <primitives:RadBusyIndicator x:Name="BusyIndicator"
                                     AnimationType="Animation6"
                                     AnimationContentColor="DodgerBlue"
                                     AnimationContentHeightRequest="100"
                                     AnimationContentWidthRequest="100"
                                     IsBusy="True">
            <primitives:RadBusyIndicator.Content>
     
                <dataControls:RadListView ItemsSource="{Binding Source=}">
                    <dataControls:RadListView.ItemTemplate>
                        <DataTemplate>
                            <listView:ListViewTextCell Text="{Binding Title}" Detail="{Binding Author}" />
                        </DataTemplate>
                    </dataControls:RadListView.ItemTemplate>
                </dataControls:RadListView>
            </primitives:RadBusyIndicator.Content>
        </primitives:RadBusyIndicator>
    </ContentPage>


    CODE-BEHIND

    [assembly:XamlCompilation(XamlCompilationOptions.Compile)]
    namespace Demo.Portable
    {
        public partial class MyPage : ContentPage
        {
            public MyPage()
            {
                InitializeComponent();
            }
     
            protected override async void OnAppearing()
            {
                base.OnAppearing();
     
                try
                {
                    BusyIndicator.IsBusy = true;
     
                    await ViewModel.LoadDataAsync();
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                }
                finally
                {
                    BusyIndicator.IsBusy = false;
                }
            }
        }
    }


    DATA MODEL

    public class BookItemViewModel : NotifyPropertyChangedBase
    {
        private string title;
        private string author;
        private bool isInStock;
     
        public string Title
        {
            get => title;
            set
            {
                title = value;
                OnPropertyChanged();
            }
        }
     
        public string Author
        {
            get => author;
            set
            {
                author = value;
                OnPropertyChanged();
            }
        }
     
        public bool IsInStock
        {
            get => isInStock;
            set
            {
                isInStock = value;
                OnPropertyChanged();
            }
        }
    }


    That code will take 3 seconds to simulate loading data, during which time the RadBusyindicator appears. When the async task is complete, the finally clause is hit and the RadBusyIndicator hides.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  4. Bill
    Bill avatar
    33 posts
    Member since:
    Nov 2017

    Posted 05 Dec 2017 Link to this post

    Thanks, that seems to work. Is there a way to make the animation fade-in when it starts, and fade-out when it ends?
  5. Bill
    Bill avatar
    33 posts
    Member since:
    Nov 2017

    Posted 05 Dec 2017 Link to this post

    Also, is there maybe a better method to place the async Task? Currently, the busy animation will freeze for maybe half a second before the page is actually displayed. It seems like the page isn't ready to be fully rendered at the point the busy animation stops.
  6. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1045 posts

    Posted 05 Dec 2017 Link to this post

    Hi Bill,

    I'm not seeing the delay, are there other synchronous methods running that would block the UIThread? The async task would not cause a UI thread freeze.

    In any case, you could try the NativeControlLoaded event for controls that have native renderers.  For example, the RadListView:

    <telerikDataControls:RadListView NativeControlLoaded="MyListView_OnNativeControlLoaded">

    private async void MyListView_OnNativeControlLoaded(object sender, EventArgs e)
    {
        try
        {
            BusyIndicator.IsBusy = true;
     
            await ViewModel.LoadDataAsync();
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
        }
        finally
        {
            BusyIndicator.IsBusy = false;
        }
    }


    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. Bill
    Bill avatar
    33 posts
    Member since:
    Nov 2017

    Posted 08 Dec 2017 in reply to Lance | Team Lead - US DevTools Support Link to this post

    Thanks for the info. What about my question about fading-in/fading-out of the animation? Any ideas for the simplest way to accomplish that?
  8. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1045 posts

    Posted 08 Dec 2017 Link to this post

    Hello Bill,

    For this, you'll want to create a custom animation. See this article for a custom animation example that fades a Label control in an in and out. The key takeaway is that the animation targets the Opacity property of the content, you can do the same for your custom animation.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top