如何使一个异步按钮点击更新TextView动态与Xamarin Android



在Xamarin Native Android应用程序中,我正在调用methodOne()并获得一些细节。在此之后,我想更新文本视图的细节,然后调用methodTwo()。在执行MethodTwo之后,我必须从文本视图中清除文本细节。我试过了RunOnUiThread() => tColorDetail。SetText("文本",TextView.BufferType.Normal));在执行MethodOne()后没有立即显示的所有方法完成后显示详细信息。这里缺少了什么?.....................................................

public class MainActivity : Activity
{
    int count = 1;
    ticket Ticket;
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);
        // Get our button from the layout resource,
        // and attach an event to it
        Button bClick= FindViewById<Button>(Resource.Id.bSub);
        try {
        bClick.Click += delegate {
            Job Job;
            Action act = new Action();
            EditText Address = (EditText)FindViewById(Resource.Id.Address);
            act.Address = Address.Text.ToString();
            if (!ValidateIPv4(act.Address))
            {
                ShowMessage("Invalid IP");
            }
            else
            {//TextView Mode = (TextView)FindViewById(Resource.Id.Mode);
                string httpUrl = act.iPAddress ;
                Ticket = act.ExecuteTicket(httpUrl, "Ticket");
                //RunOnUiThread(() => tColorMode.SetText("text", TextView.BufferType.Normal));
               // this.RunOnUiThread(() => setTicket(true));
                  setStatus(" Ticket : Success", true);
                 setTicket(true);
                //tColorMode.SetText("text",TextView.BufferType.Normal);
                //tColorMode.Invalidate();
                Job = act.executeJob(httpUrl, Ticket);
                setStatus(" Job : Success", true);
                act.File(httpUrl, Ticket, Job);
                setStatus("File Retrieval : Success", true);
                setTicket(false);
                setStatus("File Retrieval : Success", false);
            }
        };
        }
        catch (Exception ex)
        {
            ShowMessage(ex.Message.ToString());
        }
    }
    public bool ValidateIPv4(string ipString)
    {
        if (String.IsNullOrWhiteSpace(ipString))
        {
            return false;
        }
        string[] splitValues = ipString.Split('.');
        if (splitValues.Length != 4)
        {
            return false;
        }
        return true;
     }
    public  void setTicket(bool b)
    {
        //TextView tMode = (TextView)FindViewById(Resource.Id.tMode);
        // tMode.SetText("text",TextView.BufferType.Normal);
        RunOnUiThread(() => { 
        TextView tMode = (TextView)FindViewById(Resource.Id.Mode);
        tColorMode.SetText("text",TextView.BufferType.Normal);// b==true?Ticket.getProcessing():"";
        ((TextView)this.FindViewById(Resource.Id.tRes)).Text =  b == true ? Ticket.getHeight().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tFormat)).Text = b == true ? Ticket.getFormat().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tOrode)).Text = b == true ? Ticket.getType().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tRot)).Text = b == true ? Ticket.getValue().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSource)).Text = b == true ? Ticket.getSource().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSize)).Text = b == true ? Ticket.getAutoDetect().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tExpo)).Text = b == true ? Ticket.getAuto().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSharp)).Text = b == true ? Ticket.getSharp().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tComp)).Text = b == true ? Ticket.getComp().ToString() : "";
        //tColorMode.Invalidate();
    }); }
    private void ShowMessage(string msg)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog dialog = builder.Create();
        dialog.SetMessage(msg);
        dialog.SetButton("OK", (s, ev) =>
        {
            dialog.Cancel();
        });
        dialog.Show();
    }
    private void setStatus(string status,bool b)
    {
        ((TextView)this.FindViewById(Resource.Id.tStatus)).Text = b == true ? status : " ";
    }
}

没有访问完整的代码是棘手的给你一个答案,但是

Ticket = act.ExecuteTicket(httpUrl, "Ticket");

如果执行网络操作,并且可能在后台线程中运行而不是冻结UI,则这一行可能需要一段时间才能完成。

大概当你到达

    // this.RunOnUiThread(() => setTicket(true));setStatus(" Ticket : Success", true);
 setTicket(true);

。ExecuteTicket调用可能尚未完成

如果 中正在进行异步操作,也可以使用

Job = act.executeJob(httpUrl, Ticket);

可能需要一段时间来完成

综合考虑,你可能会得到

setTicket(false);
setStatus("File Retrieval : Success", false);

在第一次调用结束前

可能值得检查

在评论中讨论后回答更新:

既然你的问题是你的异步调用正在花费很长时间,你正在经历"竞争条件",因为它(你的UI线程正在进行更新的TextViews之前应该),你可以解决的情况下,改变你的按钮单击delegateasync delegate,并强迫await在长操作的结果在继续之前。

bClick.Click += async delegate {
               //...
               Job = await act.executeJob(httpUrl, Ticket);
               //...
    }

最新更新