Daron
Daron

Reputation: 117

ZXing.Net Back Navigation C#

I am using ZXing.Net camera barcode scanner, xamarin forms, and C# and it appears to be working good. But I have an issue where if I go the the next page via Navigation.PushAsync(), then click the Back Navigation Button, the ZXingScannerPage camera will not reload...(it will only be a still image of the last pic taken)...how do I reload the ZXingScannerPage so that the camera is actively upon pressing the Back Navigation? Is the anyway to refresh the camera view attached to the page?

Upvotes: 1

Views: 2440

Answers (3)

IZI
IZI

Reputation: 91

I have found a workaround which may be useful. On content page, create a local content variable. If I instantiate the scanner and add it to Content in OnAppearing method, then set Content = null OnDisappearing method. Nulling the Content seems to trigger the necessary cleanups up the stack.

Here's my code:

public class QrCodeScanPage : ZXingScannerPage
{
    View _content;
    public QrCodeScanPage()
    {
        InitScanner();
    }

    void InitScanner()
    {
        IsAnalyzing = true;
        IsScanning = true;
        DefaultOverlayTopText = "Align the barcode within the frame";
        DefaultOverlayBottomText = string.Empty;

        OnScanResult += ScanPage_OnScanResult;

        Title = "Scan Code";

        var item = new ToolbarItem
        {
            Text = "Cancel",
            Command = new Command(async () =>
            {
                IsScanning = false;
                await Navigation.PopAsync();
            })
        };
        if (Device.RuntimePlatform != Device.iOS)
            item.IconImageSource = "toolbar_close.png";

        ToolbarItems.Add(item);
    }

    void ScanPage_OnScanResult(ZXing.Result result)
    {
        Device.BeginInvokeOnMainThread(async () =>
        {
            IsScanning = false;
            IsAnalyzing = false;
            await Navigation.PushAsync(new QrCodeScanResultPage());
        });
    }

    protected override void OnAppearing()
    {
        IsScanning = true;
        IsAnalyzing = true;
        base.OnAppearing();
        if (Content != null)
        {
            _content = Content;
        }
        if (Content == null)
        {
            Content = _content;
        }
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        Content = null;
    }
}

Upvotes: 0

Daron
Daron

Reputation: 117

The solution that I found that works for me to allow back navigation using ZXing Scanner page is to remove all instances of ZXing Scanner page before push a new instance of the page to the navigation stack. In your navigation.cs, when you get ready to push the page, use this:

        foreach(var x in _navigation.Navigation.NavigationStack.ToList())
        {
          if((x.GetType() == typeof(/* name of your scanner page */)))
          {
            _navigation.Navigation.RemovePage(x);
          }
        }
        var page = new /* your scanner page */();
        _navigation.PushAsync( /* your scanner page */);

Upvotes: 0

DEV
DEV

Reputation: 949

Use the following code. Stop the scanning as soon as scanning is done. Don't do a manual manuver.

    Entry objScanner= new Entry();
                    objScanner.Placeholder = "Barcode";
                    objScanner.Keyboard = Keyboard.Numeric;
                    objScanner.HorizontalOptions = LayoutOptions.StartAndExpand;
                    objScanner.WidthRequest = Application.Current.MainPage.Width - 40;



                    objScanner.SetBinding(Entry.TextProperty, "ElementValue", BindingMode.TwoWay);
                    objScanner.BindingContext = control;


                    layout.Children.Add(objScanner);

                    objScanner.Focused +=  async (s, e) =>
                    {
                        var scanPage = new ZXingScannerPage();
                        await Navigation.PushAsync(scanPage);

                        scanPage.OnScanResult += (result) =>
                            {
                                // Stop scanning
                                scanPage.IsScanning = false;

                                // Pop the page and show the result
                                Device.BeginInvokeOnMainThread(async () =>
                               {
                                   await Navigation.PopAsync();
                                   objScanner.Text = result.Text;
                                  // await DisplayAlert("Scanned Barcode", result.Text, "OK");
                               });
                            };
                    };

Upvotes: 1

Related Questions