为啥活动指示器在 Xamarin.forms 中不起作用?

Posted

技术标签:

【中文标题】为啥活动指示器在 Xamarin.forms 中不起作用?【英文标题】:Why Activity Indicator Not working In Xamarin.forms?为什么活动指示器在 Xamarin.forms 中不起作用? 【发布时间】:2016-06-30 16:51:28 【问题描述】:

我试图显示ActivityIndicator 在我尝试更新数据库上的列字段时按下按钮后,它没有出现?有什么问题?

关于以下我的代码:

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
                
            ;

【问题讨论】:

您是如何定义 IsBusy 的?它是可绑定属性吗? ProcessToCheckOut 是按钮.. 我应该添加一个属性吗?! @StarterPack IsBusy 是内置的。它用于打开和关闭状态栏活动图标 - 但您也可以在自己的代码中使用它,就像在这里完成的那样 【参考方案1】:

this.IsBusy=true;this.IsBusy=false; 之间的代码都不是异步的。所以发生的情况是,您启用了指示器,然后继续在主线程上工作,然后在 UI 有机会更新之前禁用指示器。

要解决此问题,您需要将 appClient.UpdateInfo(user) 放入异步代码块(连同 PushAsync 和禁用活动指示器以及可能的其他一些代码)。如果您没有 UpdateInfo() 的异步版本,那么您可以将其推送到后台线程中......假设它所做的任何工作实际上对于在后台线程中运行都是安全的。

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));
        );
    );
;

请注意,一旦后台工作完成,我还使用Device.BeginInvokeOnMainThread() 将执行编组回主线程。这并不总是必要的,但这是一种很好的做法。

【讨论】:

嗨,我只是想分享一个我在这里找到并回答的稍微不同的方法:***.com/a/43119987/1605873 太棒了!在如此多的搜索和如此多的复杂代码中,一次又一次地重复,几乎没有变化,没有一个被点击。但是你如此甜美的简单代码为我创造了巨大的魔力,我为此奋斗了好几个月!万分感谢!! Device.BeginInvokeOnMainThread(() => 可能是必须的,因为没有指示符停止并且导航语句在没有实际导航的情况下通过。但是使用 Device.BeginInvokeOnMainThread(() => 实现它运行顺利。指示符停止并执行页面导航正如预期的那样。

以上是关于为啥活动指示器在 Xamarin.forms 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xamarin.Forms 中为轮播实现活动指示器?

为啥 Xamarin Forms 对所有页面使用一个 Activity

绑定到 ViewModel 在 Xamarin.Forms 中不起作用

如何在 Xamarin Forms 中更改选项卡式页面指示器的颜色

Xamarin.Forms 热重载在 UWP 中不起作用

ListView.HasUnevenRows 属性在 Xamarin.Forms.iOS 中不起作用