Raj Karri
Raj Karri

Reputation: 551

Xamarin progress dialog not showing as expected

On clicking on menu item, I need to update multiple EditText views. Code goes like this. During this process I want to show a progress dialog.

 public override bool OnOptionsItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {                
                case Resource.Id.updateid:
                    var progressDialog = ProgressDialog.Show(this, "", "Updating...", true);
                    progressDialog.SetProgressStyle(ProgressDialogStyle.Spinner);

                    new Thread(new ThreadStart(delegate
                    {
                        RunOnUiThread(() =>
                        {
                            for (int i = 0; i < 100; i++)
                            {                                
                                eTxt[i].Text = slnArray[i].ToString();                               
                            }
                            progressDialog.Dismiss();
                        }
                        );             
                    })).Start();

                    return true;
                default:
                    return base.OnOptionsItemSelected(item);
            }
        }

Sometimes the progress dialog appears and sometimes not. Mostly first time it's appearing and it's not appearing followed by. It's hung up second time.

If at all dialog appears it's not spinning and it's looking like some static image.

Question 1) How to make this dialog appear always?

Question 2) How can I make this spinning?

NOTE: I tried keeping progressDialog.Dismiss() inside another RunOnUiThread() and outside the thread also. Both the ways failed.

Upvotes: 3

Views: 6341

Answers (1)

SushiHangover
SushiHangover

Reputation: 74164

I suspect that your for (int i = 0; i < 100; i++) loop is happening so fast that the UI is not getting a chance to update the screen. Try adding in await Task.Delay (50); to simulate more work happening within your Thread.

Example:

new Thread (new ThreadStart (delegate {
    RunOnUiThread (async() => {
        for (int i = 0; i < 100; i++) {
            // Simulate some work here in order for the progress spinner to update
            await Task.Delay (50);
            //eTxt[i].Text = slnArray[i].ToString();                               
        }
        progressDialog.Dismiss ();
    }
    );             
})).Start ();

enter image description here

Note: Unless something within your Thread is actually updating the contents of the UI, you can remove the RunOnUiThread delegate as it is not needed.

new Thread (new ThreadStart (async delegate {
    for (int i = 0; i < 100; i++) {
        // Simulate some work here in order for the progress spinner to update
        await Task.Delay (50);
        //eTxt[i].Text = slnArray[i].ToString();                               
    }
    RunOnUiThread (() => {
        progressDialog.Dismiss ();
    });
})).Start ();

And even the dialog dismissal is not required to be wrapped either as the dialog's Activity/Fragment dismissal has invalidated the UI and the OS will update it on the next frame draw:

new Thread (new ThreadStart (async delegate {
    for (int i = 0; i < 100; i++) {
        // Simulate some work here in order for the progress spinner to update
        await Task.Delay (50);
        //eTxt[i].Text = slnArray[i].ToString();                               
    }
    progressDialog.Dismiss ();
})).Start ();

Upvotes: 5

Related Questions