Issue
In Xamarin/C#, How do I display the progress bar from the middle of a task instead of at completion? RunOnUiThread isn't doing the job.
I'm writing an android app using Xamarin & C#. My first activity is a login window. I don't want to move on to the next activity until login is successful. I want to display a progress bar while I check the credentials. This is where I'm stuck.
Though this is an async task, I'm doing Task.Wait() to keep from moving to the next activity before login is validated. Because of Task.Wait(), my progressBar.Visibility = ViewStates.Visible
also doesn't display until the task.Wait() is finished, which, obviously is too late.
RunOnUiThread isn't doing it. I've found answers for Java, using OnPreExecute but I can't figure out how to implement that in C#.
So again, given the event of clicking a button, how do you display the progress bar before doing the rest of the task?
UPDATE:
After implementing the solution from @Leon Lu - MSFT I still don't see the progressbar become visible. And apparently the next intent is started before logintask is complete. I can see it executing the steps in debug, but still the progressbar doesn't appear.
The progressbar does appear if I set it visible in OnCreate, so I know it's there. Perhaps I implemented the solution wrong.
Login button click handler:
[Export("btnLogin_Clicked")]
public async void btnLogin_Clicked(View view)
{
LoginActivityAsync logintask = new LoginActivityAsync(progressBar, editUsername.Text, editPassword.Text, AuthSvr);
logintask.Execute();
{
Intent MainIntent = new Intent(this, typeof(MainActivity));
MainIntent.PutExtra("ticket", _ticket);
MainIntent.PutExtra("poapiurl", ApiSvr);
StartActivityForResult(MainIntent, 0);
}
}
LoginActivtyAsync:
public class LoginActivityAsync : AsyncTask<string, int, string>
{
ProgressBar _progressbar;
private string _user;
private string _password;
private string _authsvr;
public LoginActivityAsync(ProgressBar progressBar, string user, string password, string authSvr)
{
_progressbar = progressBar;
_user = user;
_password = password;
_authsvr = authSvr;
}
protected override void OnPreExecute()
{
_progressbar.Visibility = ViewStates.Visible;
base.OnPreExecute();
}
protected override void OnPostExecute(Java.Lang.Object result)
{
base.OnPostExecute(result);
_progressbar.Visibility = ViewStates.Invisible;
}
protected override string RunInBackground(params string[] @params)
{
string ticket;
try
{
ticket = newGetAuthTicket(_authsvr, _user, _password);
}
catch (System.Exception ex)
{
throw new System.Exception(ex.Message);
}
return ticket;
}
Solution
You can use AsyncTask
to achieve it. Here is running gif.
You can write your login task in RunInBackground
method. If you want to progressbar to show, you can make the progress bar to visible
in OnPreExecute
method. If the task is finished, you can make the progress bar to Invisible
in OnPostExecute
method.
public class LoginTask : AsyncTask<string, int, string>
{
Button btn;
ProgressBar pb;
public LoginTask(ProgressBar progressBar, Button button)
{
btn = button;
pb= progressBar ;
}
protected override string RunInBackground(params string[] @params)
{
//throw new NotImplementedException();
string result = "done";
for (int i = 1; i <= 10; i++)
{
try
{
Log.Info("ttttttttttt", "doInBackground: " + i);
Thread.Sleep(500);
}
catch (InterruptedException e)
{
e.PrintStackTrace();
}
PublishProgress(i);
}
return result;
}
protected override void OnPostExecute(string result)
{
btn.Text=result;
pb.Visibility = ViewStates.Invisible;
base.OnPostExecute(result);
}
protected override void OnProgressUpdate(params int[] values)
{
base.OnProgressUpdate(values);
}
protected override void OnPreExecute()
{
pb.Visibility = ViewStates.Visible;
base.OnPreExecute();
}
}
}
I add three params in the AsyncTask
The three types used by an asynchronous task are the following:
- Params, the type of the parameters sent to the task upon execution.
- Progress, the type of the progress units published during the background computation.
- Result, the type of the result of the background computation.
Then I used in Oncreate method.
//regist for progressbar and button
loginTask= new LoginTask(progressBar, button1);
when button clicked, the task will be executed.
private async void Button1_Click(object sender, System.EventArgs e)
{
loginTask.Execute();
}
Answered By - Leon Lu - MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.