如何为 ZXing Scanner 创建和实现 Android CustomOverlay? [英] How to create and implement a Android CustomOverlay for ZXing Scanner?

查看:24
本文介绍了如何为 ZXing Scanner 创建和实现 Android CustomOverlay?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的 Xamarin.Forms 项目使用 ZXing 条形码扫描仪插件.根据一些帖子,我需要为 ZXing 扫描仪使用自定义叠加层才能有取消按钮.但我不熟悉 Xamarin.Forms 项目中的 Android 开发.

到目前为止,我知道一个扫描器(ZXing 插件的 MobileBarcodeScanner)接受一个 Android.Views.View 作为覆盖来替换默认的扫描页面视图.

public async Task扫描异步(){MobileBarcodeScanner 扫描仪 = new MobileBarcodeScanner();扫描仪.UseCustomOverlay = true;扫描仪.CustomOverlay = ???????;var scanResult = 等待scanner.Scan();如果(扫描结果!= null){ 返回 scanResult.Text;}返回空;}

但我不知道如何创建视图页面(以 XML 设计或以编程方式)并将其设置为scanner.CustomOverlay.

我不确定是否可以将常见的 Android 视图用于扫描仪,任何详细的参考资料都会非常有用.

谢谢.

解决方案

如果要自定义叠加层,则必须为每个平台创建自己的视图.您可以像这样自定义叠加层(创建一个名为 ZxingOverlayView 的自定义叠加层,将其设置为 scanner.CustomOverlay):

var scanner = new ZXing.MobileMobileBarcodeScanner();扫描仪.UseCustomOverlay = true;myCustomOverlayInstance = new ZxingOverlayView(this,scanner);扫描仪.CustomOverlay = myCustomOverlayInstance;

ZxingOverlayView 应该继承 view 然后将您的控件添加到自定义视图中.您可以查看有关此链接的详细信息.

这是一个很好的简单代码.你可以参考一下.https://github.com/Wenfengcheng/ZXing.Sample_Xamarin

I'm using ZXing barcode scanner plugin for my Xamarin.Forms project. According to some posts, I need to use custom overlay for ZXing scanner in order to have cancel button. But I'm not familiar with Android development in a Xamarin.Forms project.

So far, I know a scanner (MobileBarcodeScanner of ZXing plugin) accept an Android.Views.View as an overlay to replace the default scanning page view.

public async Task<string> ScanAsync()
{
    MobileBarcodeScanner scanner = new MobileBarcodeScanner();
    scanner.UseCustomOverlay = true;
    scanner.CustomOverlay = ???????;

    var scanResult = await scanner.Scan();
    if (scanResult != null)
    { return scanResult.Text; }
    return null;
}

But I don't know how to create a view page (either in XML design or programmatically) and set it to scanner.CustomOverlay.

I'm not sure if a common Android view can be used for scanner, any detailed reference would be really appreicated.

Thanks.

解决方案

If you want to customize the overlay, you must create your own View for each platform. You can customize your overlay like this( create a custom overlay called ZxingOverlayView set it to the scanner.CustomOverlay):

var scanner = new ZXing.MobileMobileBarcodeScanner();
scanner.UseCustomOverlay = true;
myCustomOverlayInstance = new ZxingOverlayView(this, scanner);
scanner.CustomOverlay = myCustomOverlayInstance;

ZxingOverlayView should inherit the view then add your control to the custom view. You can see details about this link.

http://slackshotindustries.blogspot.com/2013/04/creating-custom-overlays-in-xzing.html

Edit

There are completely steps.

First of all, you could create a interface for dependence service.

 public interface IDeviceService
  {
    Task<string> ScanAsync();
  }

You can use this interface in the PCL code.

  private async void DependencyButton_Clicked(object sender, EventArgs e)
    {
        var result = await DependencyService.Get<IDeviceService>().ScanAsync();
        if (!string.IsNullOrEmpty(result))
        {
            await DisplayAlert(result, null, "OK");
        }
    }

In the android platform. You can design your layout. First of all, create a layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
    android:id="@+id/imgClose"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:src="@drawable/close"
    android:layout_marginTop="20dp"
    android:layout_marginLeft="20dp"/>
  <RelativeLayout
    android:id="@+id/llScan"
    android:layout_width="240dp"
    android:layout_height="240dp"
    android:layout_centerInParent="true"
    android:background="@drawable/scan">
  <ImageView
        android:id="@+id/imgLine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:src="@drawable/scan_line"
        android:layout_centerHorizontal="true" />
     </RelativeLayout>
  <View
    android:id="@+id/viewTop"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/llScan"
    android:background="@color/title_black"/>
 <View
    android:id="@+id/viewBottom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/llScan"
    android:background="@color/title_black"
    android:layout_alignParentBottom="true"/>
 <View
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/viewTop"
    android:layout_toLeftOf="@id/llScan"
    android:layout_above="@id/viewBottom"
    android:background="@color/title_black"/>
 <View
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/viewTop"
    android:layout_above="@id/viewBottom"
    android:layout_toRightOf="@id/llScan"
    android:background="@color/title_black"/>
 </RelativeLayout>

Then achieve the dependence service interface and use your new layout.

 [assembly: Xamarin.Forms.Dependency(typeof(DeviceService))]
 namespace Sample.Droid
 {
  public class DeviceService : IDeviceService
 {
    public async Task<string> ScanAsync()
    {
        var scanner = new ZXing.Mobile.MobileBarcodeScanner
        {
            UseCustomOverlay = true

        };
        //scanner.CustomOverlay = new CustomScanView(Application.Context);
        var options = new ZXing.Mobile.MobileBarcodeScanningOptions()
        {
            TryHarder = true,
            AutoRotate = false,
            UseFrontCameraIfAvailable = false,
            CameraResolutionSelector = new CameraResolutionSelectorDelegate(SelectLowestResolutionMatchingDisplayAspectRatio),
            PossibleFormats = new List<ZXing.BarcodeFormat>()
            {
                ZXing.BarcodeFormat.QR_CODE
            }
        };

        View scanView = LayoutInflater.From(Application.Context).Inflate(Resource.Layout.ScanView, null);
        ImageView imgLine = scanView.FindViewById<ImageView>(Resource.Id.imgLine);
        ImageView imgClose = scanView.FindViewById<ImageView>(Resource.Id.imgClose);
        imgClose.Click += delegate
        {
            scanner.Cancel();
        };
        scanner.CustomOverlay = scanView;

        ObjectAnimator objectAnimator = ObjectAnimator.OfFloat(imgLine, "Y", 0, DpToPixels(240));
        objectAnimator.SetDuration(2500);
        objectAnimator.RepeatCount = -1;
        objectAnimator.SetInterpolator(new LinearInterpolator());
        objectAnimator.RepeatMode = ValueAnimatorRepeatMode.Restart;
        objectAnimator.Start();

        ZXing.Result scanResults = await scanner.Scan(CrossCurrentActivity.Current.Activity, options);
        if (scanResults != null)
        {
            return scanResults.Text;
        }
        return string.Empty;
    }

    private int DpToPixels(double dp)
    {
        return (int)(dp * Application.Context.Resources.DisplayMetrics.Density);
    }

    private CameraResolution SelectLowestResolutionMatchingDisplayAspectRatio(List<CameraResolution> availableResolutions)
    {
        CameraResolution result = null;
        //a tolerance of 0.1 should not be visible to the user
        double aspectTolerance = 0.1;
        var displayOrientationHeight = DeviceDisplay.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? DeviceDisplay.MainDisplayInfo.Height : DeviceDisplay.MainDisplayInfo.Width;
        var displayOrientationWidth = DeviceDisplay.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? DeviceDisplay.MainDisplayInfo.Width : DeviceDisplay.MainDisplayInfo.Height;
        //calculatiing our targetRatio
        var targetRatio = displayOrientationHeight / displayOrientationWidth;
        var targetHeight = displayOrientationHeight;
        var minDiff = double.MaxValue;
        //camera API lists all available resolutions from highest to lowest, perfect for us
        //making use of this sorting, following code runs some comparisons to select the lowest resolution that matches the screen aspect ratio and lies within tolerance
        //selecting the lowest makes Qr detection actual faster most of the time
        foreach (var r in availableResolutions.Where(r => Math.Abs(((double)r.Width / r.Height) - targetRatio) < aspectTolerance))
        {
            //slowly going down the list to the lowest matching solution with the correct aspect ratio
            if (Math.Abs(r.Height - targetHeight) < minDiff)
                minDiff = Math.Abs(r.Height - targetHeight);
            result = r;
        }
        return result;
    }
   }

}

IOS code.

[assembly: Xamarin.Forms.Dependency(typeof(DeviceService))]
namespace Sample.iOS
{
public class DeviceService : IDeviceService
{
    public async Task<string> ScanAsync()
    {
        var scanner = new ZXing.Mobile.MobileBarcodeScanner()
        {
            UseCustomOverlay = true
        };

        var options = new ZXing.Mobile.MobileBarcodeScanningOptions()
        {
            TryHarder = true,
            AutoRotate = false,
            UseFrontCameraIfAvailable = false,
            PossibleFormats = new List<ZXing.BarcodeFormat>()
            {
                ZXing.BarcodeFormat.QR_CODE
            }
        };

        ScannerOverlayView customOverlay = new ScannerOverlayView();
        customOverlay.OnCancel += () =>
        {
            scanner?.Cancel();
        };
        customOverlay.OnResume += () =>
        {
            scanner?.ResumeAnalysis();
        };
        customOverlay.OnPause += () =>
        {
            scanner?.PauseAnalysis();
        };
        scanner.CustomOverlay = customOverlay;


        ZXing.Result scanResults = null;
        scanResults = await scanner.Scan(options);
        //customOverlay.Dispose();
        if (scanResults != null)
        {
            return scanResults.Text;
        }
        return string.Empty;
    }
}

Here is running GIF.

Here is a good simple code. you could refer to it. https://github.com/Wenfengcheng/ZXing.Sample_Xamarin

这篇关于如何为 ZXing Scanner 创建和实现 Android CustomOverlay?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆