maxspan
maxspan

Reputation: 14147

Navigating from xamarin android to PCL

I am currently using xamarin form with PCL to accessing camera and scan barcodes and show it in a UserDialog . I can do that easily using dependency service. The issue I am having is going back. I want to go back to the PCL by pressing the cancel button on the userDialog. I am using messagingcenter to go back to PCL home page and the message do go back but the UI stay the same i.e the camera screen stays there.

Below is my code

void HandleScanResult(ZXing.Result result)
{
    if (result != null && !string.IsNullOrEmpty(result.Text))
    {
        CrossVibrate.Current.Vibration(500);
    }

    Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
    {
        resultText.Text = await SaveScannedRecord(result.Text);
        PromptResult promptResult = await UserDialogs.Instance.PromptAsync
        ("Hello Friends","Question","SCAN","CANCEL",resultText.Text,InputType.Name);     
        if (promptResult.Ok)
        {

        }
        else
        {
            //CODE TO GO BACK
            var home = new Home();
            RunOnUiThread(() => { xamarinForm.MessagingCenter.Send<Home>(home, "scannedResult"); });

        }
    });
}

Upvotes: 0

Views: 793

Answers (2)

Eugene
Eugene

Reputation: 1789

In such situations, I really like to use async/await syntax:

1) Define somewhere in class TaskCompletionSource<bool> variable

2) When you call your method, initialize that variable:

public async Task<bool> Scan()
{
   // init task variable
   tsc = new TaskCompletionSource<bool>();

   // call your method for scan (from ZXing lib)
   StartScan(); 

   // return task from source
   return tsc.Task;
}

3) When handle result, set result for task:

void HandleScanResult(ZXing.Result result)
{
   Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
   {
       resultText.Text = await SaveScannedRecord(result.Text);
       PromptResult promptResult = await UserDialogs.Instance.PromptAsync("Hello Friends", "Question", "SCAN", "CANCEL", resultText.Text, InputType.Name);
       if (promptResult.Ok)
       {
         tsc.SetResult(true);
       }
       else
       {
         //CODE TO GO BACK
         tsc.SetResult(false);
       }
    });    
}

Now you can write navigation logic in PCL, like that:

var scanResult = await scanService.Scan();
if (!scanResult)
   // your navigation logic goes here
   Navigation.PopToRoot();

Upvotes: 2

Mario Galv&#225;n
Mario Galv&#225;n

Reputation: 4032

@Eugene Solution is a great one, nevertheless you can still use the Messaging center:

I believe the problem is right here:

xamarinForm.MessagingCenter.Send<Home>(home, "scannedResult"); });

//Solution:
MessagingCenter.Send<Home> (this, "scannedResult");
//Inside the PCL you will need:
MessagingCenter.Subscribe<Home> (this, "scannedResult", (sender) => {
    // do your thing.
});

Upvotes: 0

Related Questions