如何使用 DependencyService 和接口委托将 xamarin.android 特定功能的方法传递给 xamarin.forms?

Posted

技术标签:

【中文标题】如何使用 DependencyService 和接口委托将 xamarin.android 特定功能的方法传递给 xamarin.forms?【英文标题】:How to pass a method of xamarin.android specific functionnality to a xamarin.forms using DependencyService and a delegate of Interface? 【发布时间】:2020-05-12 07:39:13 【问题描述】:

我正在使用以下资源https://msicc.net/how-to-avoid-a-distorted-android-camera-preview-with-zxing-net-mobile/ 来解决zxing 条码扫描器的分辨率损坏问题。我到达了在 android 项目中实现方法 SelectLowestResolutionMatchingDisplayAspectRatio 的地方,但我需要将它传递给 CameraResolutionSelectorDelegate,正如作者所说。为此,我创建了一个名为 IZXingHelper 的接口,它应该包含我仍然不知道应该如何编写的委托。让我分享我的代码 sn-p 并解释我面临的问题。

public class ZxingHelperAndroid : IZXingHelper
    

     //What code goes here?

        public 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;
        
    

这里正是我无法确定要写什么才能做到正确的地方:

zxing.Options = new ZXing.Mobile.MobileBarcodeScanningOptions
            
                CameraResolutionSelector = DependencyService.Get<IZXingHelper>().CameraResolutionSelectorDelegateImplementation
            ;
public interface IZXingHelper

 //What code goes here?


我不知道如何在接口中实现CameraResolutionSelectorDelegateImplementation以及如何将其链接到SelectLowestResolutionMatchingDisplayAspectRatio ZxingHelperAndroid的方法。

【问题讨论】:

【参考方案1】:

在 Xamarin.forms Demo 中创建接口 IZXingHelper。

public interface IZXingHelper

    //CameraResolutionSelectorDelegateImplementation
    CameraResolution SelectLowestResolutionMatchingDisplayAspectRatio(List<CameraResolution> availableResolutions);

在.Android项目中创建ZXingHelper.cs来实现。

using System;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Essentials;
using ZXing.Mobile;

// Because the assembly dependency decoration is outside of the namespace,
// the namespace "using" must be added or be explicitly prefixed to the
// typeof parameter.

using ScorellViewDemo.Droid;

[assembly: Xamarin.Forms.Dependency(typeof(ZXingHelper))]
namespace ScorellViewDemo.Droid

  public class ZXingHelper : IZXingHelper
  
    public 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;

      //calculating 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;
    
  

在 MainPage.xaml.cs 中的使用

 var options = new ZXing.Mobile.MobileBarcodeScanningOptions()
 
   PossibleFormats = new List<ZXing.BarcodeFormat>()  ZXing.BarcodeFormat.QR_CODE ,
   CameraResolutionSelector = DependencyService.Get<IZXingHelper>().SelectLowestResolutionMatchingDisplayAspectRatio
 ;

【讨论】:

非常感谢这段代码。终于找到了一个使用依赖注入的例子

以上是关于如何使用 DependencyService 和接口委托将 xamarin.android 特定功能的方法传递给 xamarin.forms?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms 相机控制访问 DependencyService

Xamarin.Forms中DependencyService的使用

Xamarin.Forms DependencyService 始终返回 null

Xamarin+Prism开发详解六:DependencyService与IPlatformInitializer的关系

如何获得 ActiveMQ - 单个发送方和接收方的 FIFO 要求?

如何在 UDP 广播中处理同时作为发送方和接收方的客户端