Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Activity Indicator Not working In Xamarin.forms?

I am trying to display ActivityIndicator After I press a button while I am trying to update The Column Field On DataBase, it is not appearing? What is the problem?

On the following My Code:

ActivityIndicator ai = new ActivityIndicator()
            {
                HorizontalOptions = LayoutOptions.CenterAndExpand,
                Color = Color.Black
            };
            ai.IsRunning = true;
            ai.IsEnabled = true;
            ai.BindingContext = this;
            ai.SetBinding(ActivityIndicator.IsVisibleProperty, "IsBusy");

            ProcessToCheckOut = new Button { Text = "Set Inf" };
            ProcessToCheckOut.Clicked += (object sender, EventArgs e) =>
            {
                this.IsBusy = true;
                UserUpdateRequest user=new UserUpdateRequest();
                user.userId = CustomersPage.ID;
                appClient.UpdateInfo(user);                  
                this.IsBusy = false;
                Navigation.PushAsync(new CheckoutShippingAddressPage(appClient));
            };
         Content = new StackLayout
            {
                Children={
                tb,
                ai,
                ProcessToCheckOut
                }
            };
like image 281
Mohamad Mahmoud Avatar asked Mar 15 '16 10:03

Mohamad Mahmoud


1 Answers

None of the code between this.IsBusy=true; and this.IsBusy=false; is asynchronous. So what is happening is that you enable the indicator but then continue to do work on the main thread and then disable the indicator before the UI has a chance to update.

To fix this, you would need to put appClient.UpdateInfo(user) into an async code block (along with the PushAsync and disabling of activity indicator and probably some of the other code). If you don't have an async version of UpdateInfo() then you can push it off into a background thread... assuming whatever work it does is actually safe for running in a background thread.

ProcessToCheckOut.Clicked += (object sender, EventArgs e) =>
{
    this.IsBusy = true;
    var id = CustomersPage.ID;
    Task.Run(() => {
        UserUpdateRequest user=new UserUpdateRequest();
        user.userId = id;
        appClient.UpdateInfo(user);
        Device.BeginInvokeOnMainThread(() => {
            this.IsBusy = false;
            Navigation.PushAsync(new CheckoutShippingAddressPage(appClient));
        });
    });
};

Note that I also used Device.BeginInvokeOnMainThread() to marshal execution back to the main thread once the background work is done. This isn't always necessary but it is good practice.

like image 191
Keith Rome Avatar answered Sep 28 '22 04:09

Keith Rome