微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 ZXing Net Mobile 在 Xamarin Forms 中在 Android 上实现手电筒按钮

如何解决如何使用 ZXing Net Mobile 在 Xamarin Forms 中在 Android 上实现手电筒按钮

我正在寻找一种干净的方法来使用 Zxing Net Mobile NuGet 包为条形码扫描仪创建带有手电筒按钮的(自定义)覆盖。

我已经看过一些示例,但不幸的是,这些示例使用的是干净的 Xamarin 而没有 MvvmCross。

下面的代码放在一个自定义的“ScannerService”中,它在 Mvxviewmodel (Scanviewmodel) 中被调用

到目前为止我得到了什么:

IScannerService.cs

public class ScannerService : IScannerService
{
    public void Scan(Action<Result> onComplete)
    {
        MobileBarcodeScanner.Initialize(Xamarin.Essentials.Platform.CurrentActivity.Application);
        MobileBarcodeScanner scanner = new MobileBarcodeScanner
        {
            TopText = "Houd uw telefoon voor de barcode.",FlashButtonText = "Flitser",CancelButtonText = "Stoppen",BottomText = "Het scannen gebeurt automatisch."
        };

        var overlay = new ZxingOverlayView(Xamarin.Essentials.Platform.CurrentActivity.Application);
        var button = new Button();
        button.Clicked += (sender,e) => scanner.Toggletorch();
        overlay.AddChildrenForAccessibility(button);

        scanner.UseCustomOverlay = true;
        scanner.CustomOverlay = overlay;

        bool result = false;
        scanner.ScanContinuously((scanResult) =>
        {
            if (!result)
            {
                result = true;
                scanner.Cancel();
                Device.BeginInvokeOnMainThread(() => onComplete(scanResult));
            }
        });
    }
}

问题是我创建了一个 Xamarin.Forms Button 并且无法将此按钮添加到“ZxingOverlayView”的自定义叠加层。

Scanviewmodel.cs

    private async Task Scan()
    {
        if (await _mediaService.CheckPermissions().ConfigureAwait(false))
        {
            _scanner.Scan((result) => MvxNotifyTask.Create(() => MainThread.InvokeOnMainThreadAsync(() => HandleScan(result)),OnException));
        }
    }

是否有其他方法可以将手电筒按钮添加自定义叠加层?

编辑:

正如 Leo 建议的那样,我使用了 ZXing.Net.Mobile认示例。我在页面添加了“ZXingDefaultOverlay”,但不幸的是,每次我在页面中使用 ZXing 组件时,它都会引发以下异常:

java.lang.NullPointerException: '尝试在空对象引用上调用虚拟方法 'android.content.res.Resources android.content.Context.getResources()'

这是我目前的代码

Scanningviewmodel.cs(Baseviewmodel 继承自 'Mvxviewmodel')

public class Scanningviewmodel : Baseviewmodel
{
    private readonly IMvxNavigationService _navigationService;
    private readonly IUserDialogs _userDialogs;

    ZXingScannerView ZXingScannerView;
    ZXingDefaultOverlay ZXingDefaultOverlay;

    private Grid _grid;

    public Grid Grid
    {
        get => _grid;
        set => SetProperty(ref _grid,value);
    }

    public Scanningviewmodel(IMvxNavigationService navigationService,IUserDialogs userDialogs)
    {
        _navigationService = navigationService;
        _userDialogs = userDialogs;

        ZXingScannerView = new ZXingScannerView
        {
            HorizontalOptions = Layoutoptions.FillAndExpand,VerticalOptions = Layoutoptions.FillAndExpand,AutomationId = "zxingScannerView"
        };
        ZXingScannerView.OnScanResult += (result) =>
        Device.BeginInvokeOnMainThread(async () =>
        {
            // Stop analysis until we navigate away so we don't keep reading barcodes
            ZXingScannerView.IsAnalyzing = false;

            // Show an alert
            await _userDialogs.AlertAsync("Scanned Barcode",result.Text,"OK");
        });

        ZXingDefaultOverlay = new ZXingDefaultOverlay
        {
            TopText = "",BottomText = "",ShowFlashButton = true,AutomationId = "zxingDefaultOverlay"
        };
        ZXingDefaultOverlay.FlashButtonClicked += (sender,e) =>
        {
            ZXingScannerView.IsTorchOn = !ZXingScannerView.IsTorchOn;
        };

        var grid = new Grid
        {
            HorizontalOptions = Layoutoptions.FillAndExpand,VerticalOptions = Layoutoptions.FillAndExpand
        };

        var stopButton = new Button
        {
            WidthRequest = 100,HeightRequest = 50,HorizontalOptions = Layoutoptions.Start,VerticalOptions = Layoutoptions.End,Text = "disable",Command = new Command(() => ZXingScannerView.IsScanning = false)
        };

        var cancelButton = new Button
        {
            WidthRequest = 100,HorizontalOptions = Layoutoptions.Center,Text = "Cancel",Command = new Command(async () => await _navigationService.Close(this))
        };

        var startButton = new Button
        {
            WidthRequest = 100,HorizontalOptions = Layoutoptions.End,Text = "Enable",Command = new Command(() => ZXingScannerView.IsScanning = true)
        };

        grid.Children.Add(ZXingScannerView);
        grid.Children.Add(ZXingDefaultOverlay);
        grid.Children.Add(startButton);
        grid.Children.Add(cancelButton);
        grid.Children.Add(stopButton);

        // The root page of your application
        Grid = grid;
    }

    //protected override void OnAppearing()
    //{
    //    base.OnAppearing();

    //    ZXingScannerView.IsScanning = true;
    //}

    //protected override void Ondisappearing()
    //{
    //    ZXingScannerView.IsScanning = false;

    //    base.Ondisappearing();
    //}
}

ScanningPage.xaml(这是一个“MvxContentPage”)

<ContentPage.Content>
    <StackLayout>
        <ContentView Content="{Binding Grid}"></ContentView>
    </StackLayout>
</ContentPage.Content>

ScanningPage.xaml.cs

[MvxContentPagePresentation(WrapInNavigationPage = true)]
public partial class ScanningPage : MvxContentPage<Scanningviewmodel>
{
    public ScanningPage()
    {
        InitializeComponent();
    }
}

知道为什么会抛出这个特定的错误吗?

我使用“ZXing.Net.Mobile”和“ZXing.Net.Mobile.Forms”NuGet 包的 2.4.1 版。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。