在等待操作完成时显示ProgressBar

时间:2016-02-08 17:10:01

标签: android xamarin xamarin.android mvvmcross android-progressbar

在我的MVVMCross App中,我将Android ProgressBar定义为:

onPreExecute

在ViewModel中,单击按钮开始操作时执行的代码如下:

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:progressDrawable="@drawable/circular_progress_bar"
    android:gravity="right"
    local:MvxBind="Visibility Visibility(IsBusy)" />

但除非我删除最后一个public void Next() { IsBusy = true; try { //THE EXPENSIVE OPERATION var response = CallTimeConsumingService(); if (response.MethodFailed) { _dialogService.DisplayAlert(this, response.Message); return; } ShowViewModel<ShowNextView>(); } catch (Exception ex) { _dialogService.DisplayAlert(this, ex.Message); } IsBusy = false; } ,否则不会显示ProgressBar, 但是这意味着只有在Next()方法退出时才会显示(而不是在等待时)

在导航到下一页之前,如何在等待和禁用ProgressBar时显示ProgressBar?

=== EDIT ====

结束这样做:

IsBusy = false;

将其余代码添加到DoWork,等待任务

public void Next()
{
   async () =>
       {
           IsBusy = true;
           await DoWork();
           IsBusy = false;
       });
}

2 个答案:

答案 0 :(得分:2)

这种情况正在发生,因为更新UI的过程当前正在与昂贵的操作相同的线程中进行。在您的操作完成之前,UI线程将被阻止,并且视觉反馈永远不会正确显示。要解决此问题,您需要将#chatApplicationClassic { padding: 0; margin: 0; border: 0; position: fixed; bottom: 0px; right: 30px; width: 300px; background-color: pink; box-sizing: border-box; border-radius: 5px 5px 0 0; box-shadow: 0px 0px 5px #000000; 变为异步调用(使其返回CallTimeConsumingService())并Task<T>才能完成。

如果您的方法中有网络调用,则阻止方法具有已经等待的异步对等方。如果您的方法只涉及繁重的处理,则应使用TaskCompletionSourceTask.Run

答案 1 :(得分:1)

以前的答案是正确的,但您可以通过使next()方法为异步来编写更干净的代码:

public async Task Next()
{
    IsBusy = true;

    try
    {
        //THE EXPENSIVE OPERATION
        var response = await CallTimeConsumingServiceReturningTask();

        if (response.MethodFailed)
        {
            _dialogService.DisplayAlert(this, response.Message);
            return;
        }

        ShowViewModel<ShowNextView>();
    }
    catch (Exception ex)
    {
        _dialogService.DisplayAlert(this, ex.Message);
    }

    IsBusy = false;
}