Skip to content

Instantly share code, notes, and snippets.

@rotorgames
Created March 27, 2019 05:28
Show Gist options
  • Select an option

  • Save rotorgames/f6ebe495a0c6325c6499de7e0119140d to your computer and use it in GitHub Desktop.

Select an option

Save rotorgames/f6ebe495a0c6325c6499de7e0119140d to your computer and use it in GitHub Desktop.
BarcodePickerView Xamarin.Forms
using System.Windows.Input;
using Xamarin.Forms;
using System;
using System.ComponentModel;
using Scandit.BarcodePicker.Unified.Abstractions;
namespace ProjectName.Controls.BarcodeScanner
{
public class BarcodePickerView : View
{
public event EventHandler<ScanSession> BarcodeDetected;
public static readonly BindableProperty IsStartedProperty = BindableProperty.Create(nameof(IsStarted), typeof(bool), typeof(BarcodePickerView), false);
public bool IsStarted
{
get { return (bool)GetValue(IsStartedProperty); }
set { SetValue(IsStartedProperty, value); }
}
public static readonly BindableProperty IsTorchOnProperty = BindableProperty.Create(nameof(IsTorchOn), typeof(bool), typeof(BarcodePickerView), false);
public bool IsTorchOn
{
get { return (bool)GetValue(IsTorchOnProperty); }
set { SetValue(IsTorchOnProperty, value); }
}
public static readonly BindableProperty IsBeepEnabledProperty = BindableProperty.Create(nameof(IsBeepEnabled), typeof(bool), typeof(BarcodePickerView), false);
public bool IsBeepEnabled
{
get { return (bool)GetValue(IsBeepEnabledProperty); }
set { SetValue(IsBeepEnabledProperty, value); }
}
public static readonly BindableProperty CodeDuplicateFilterProperty = BindableProperty.Create(nameof(CodeDuplicateFilter), typeof(int), typeof(BarcodePickerView), 500);
public int CodeDuplicateFilter
{
get { return (int)GetValue(CodeDuplicateFilterProperty); }
set { SetValue(CodeDuplicateFilterProperty, value); }
}
public static readonly BindableProperty BarcodeDetectedCommandProperty = BindableProperty.Create(nameof(BarcodeDetectedCommand), typeof(ICommand), typeof(BarcodePickerView));
public ICommand BarcodeDetectedCommand
{
get { return (ICommand)GetValue(BarcodeDetectedCommandProperty); }
set { SetValue(BarcodeDetectedCommandProperty, value); }
}
public static readonly BindableProperty BarcodeDetectedCommandParameterProperty = BindableProperty.Create(nameof(BarcodeDetectedCommandParameter), typeof(object), typeof(BarcodePickerView));
public object BarcodeDetectedCommandParameter
{
get { return (object)GetValue(BarcodeDetectedCommandParameterProperty); }
set { SetValue(BarcodeDetectedCommandParameterProperty, value); }
}
public static readonly BindableProperty SymbologiesProperty = BindableProperty.Create(nameof(Symbologies), typeof(Symbology), typeof(BarcodePickerView), Symbology.All);
public Symbology Symbologies
{
get { return (Symbology)GetValue(SymbologiesProperty); }
set { SetValue(SymbologiesProperty, value); }
}
public static readonly BindableProperty CameraPositionPreferenceProperty = BindableProperty.Create(nameof(CameraPositionPreference), typeof(CameraPosition), typeof(BarcodePickerView), CameraPosition.Back);
public CameraPosition CameraPositionPreference
{
get { return (CameraPosition)GetValue(CameraPositionPreferenceProperty); }
set { SetValue(CameraPositionPreferenceProperty, value); }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public void SendBarcodeDetected(ScanSession session)
{
BarcodeDetected?.Invoke(this, session);
BarcodeDetectedCommand?.Execute(BarcodeDetectedCommandParameter ?? session);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using Android.Content;
using Android.Media;
using Android.Views;
using ScanditBarcodePicker.Android;
using ProjectName.Controls.BarcodeScanner;
using ProjectName.Droid.Extensions.BarcodeScanner;
using ProjectName.Droid.Renderers.BarcodeScanner;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Barcode = ScanditBarcodePicker.Android.Recognition.Barcode;
using ScanSettings = ScanditBarcodePicker.Android.ScanSettings;
using Symbology = ProjectName.Controls.BarcodeScanner.Symbology;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof(BarcodePickerView), typeof(BarcodePickerViewRenderer))]
namespace ProjectName.Droid.Renderers.BarcodeScanner
{
public class BarcodePickerViewRenderer : ViewRenderer<BarcodePickerView, BarcodePicker>
{
public BarcodePickerViewRenderer(Context context):base(context)
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Control.Scan -= OnScanDetected;
}
base.Dispose(disposing);
}
protected override void OnElementChanged(ElementChangedEventArgs<BarcodePickerView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var control = CreateNativeControl();
control.Scan += OnScanDetected;
SetNativeControl(control);
}
if (e.NewElement != null)
{
UpdateState();
UpdateSettings();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
switch (e.PropertyName)
{
case nameof(BarcodePickerView.IsStarted):
case nameof(BarcodePickerView.IsTorchOn):
case nameof(BarcodePickerView.IsBeepEnabled):
UpdateState();
break;
case nameof(BarcodePickerView.Symbologies):
case nameof(BarcodePickerView.CameraPositionPreference):
UpdateSettings();
break;
}
}
protected override BarcodePicker CreateNativeControl()
{
var control = new BarcodePicker(Context);
var overlayView = control.OverlayView;
//overlayView.SetGuiStyle(GuiStyle.None.ToAndroidGuiStyle());
overlayView.SetTorchEnabled(false);
overlayView.SetBeepEnabled(false);
//Remove the default camera permission missing message
overlayView.SetMissingCameraPermissionInfoText(string.Empty);
return control;
}
protected override void OnVisibilityChanged(View changedView, ViewStates visibility)
{
base.OnVisibilityChanged(changedView, visibility);
if(visibility == Visibility)
UpdateState();
}
private void OnScanDetected(object sender, ScanEventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
var session = e.P0?.ToPortable();
if (session == null || Element?.IsStarted != true)
return;
if (session.AllRecognizedCodes.Count == 1 && session.NewlyRecognizedCodes.Count == 0)
session.NewlyRecognizedCodes.Add(session.AllRecognizedCodes[0]);
if (!session.NewlyRecognizedCodes.Any())
return;
Element?.SendBarcodeDetected(session);
});
}
private void UpdateState()
{
if(Element == null || Control == null)
return;
var control = Control;
if (Element.IsStarted)
UpdateSettings();
if(Element.IsStarted)
control.StartScanning(false);
else
control.StopScanning();
control.SwitchTorchOn(Element.IsTorchOn);
control.OverlayView.SetBeepEnabled(Element.IsBeepEnabled);
}
#region Settings
private ScanSettings GetScanSettings()
{
var settings = ScanSettings.Create();
settings.CodeDuplicateFilter = 3000;
var enabledSymbologies = GetEnabledSymbologies(Element.Symbologies);
foreach (var enabledSymbology in enabledSymbologies)
settings.SetSymbologyEnabled(enabledSymbology, true);
var cameraFacing = Element.CameraPositionPreference == Scandit.BarcodePicker.Unified.Abstractions.CameraPosition.Back ?
ScanSettings.CameraFacingBack :
ScanSettings.CameraFacingFront;
settings.CameraFacingPreference = cameraFacing;
return settings;
}
#endregion
#region Symbologies
private void UpdateSettings()
{
var control = Control;
var settings = GetScanSettings();
control.ApplyScanSettings(settings);
}
private IList<int> GetEnabledSymbologies(Symbology symbology)
{
var symbologies = new List<int>();
if (symbology.Equals(Symbology.All))
return Barcode.AllSymbologies;
foreach (Symbology symb in Enum.GetValues(typeof(Symbology)))
{
if (symb == Symbology.All)
continue;
if (symbology.HasFlag(symb))
symbologies.Add(GetIntForSymbology(symb));
}
return symbologies;
}
private int GetIntForSymbology(Symbology symbology)
{
var symbologyName = Enum.GetName(typeof(Symbology), symbology);
var property = typeof(Barcode).GetProperty("Symbology" + symbologyName,
BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase);
if (property == null)
throw new InvalidOperationException($"There is not {symbology} symbology");
var value = (int) property.GetValue(null);
return value;
}
#endregion
}
}
<!--This is a part of the real code in the project-->
<barcodeScanner:BarcodePickerView
Symbologies="Code128, Ean13, Ean8, DataMatrix, Qr, Gs1Databar, Gs1DatabarExpanded"
IsBeepEnabled="{Binding IsBeepOn}"
IsStarted="{Binding IsScannerStarted}"
IsTorchOn="{Binding IsTurnTorcOn}"
CameraPositionPreference="{Binding CameraPositionPreference}"
BarcodeDetectedCommand="{Binding BarcodeDetectedCommand}"
BarcodeDetected="OnBarcodeDetected"/>
using System.Linq;
using Scandit;
using ScanditBarcodePicker.Android;
using ProjectName.Controls.BarcodeScanner;
namespace ProjectName.Droid.Extensions.BarcodeScanner
{
public static class ScanSessionExtension
{
public static ScanSession ToPortable(this IScanSession session)
{
return new ScanSession
{
AllRecognizedCodes = session.AllRecognizedCodes?.Select(barcode => barcode.ToBarcode()).ToList(),
NewlyLocalizedCodes = session.NewlyLocalizedCodes?.Select(barcode => barcode.ToBarcode()).ToList(),
NewlyRecognizedCodes = session.NewlyRecognizedCodes?.Select(barcode => barcode.ToBarcode()).ToList(),
};
}
}
}
using System;
namespace ProjectName.Controls.BarcodeScanner
{
[Flags]
public enum Symbology
{
All = 0,
Ean13 = 1,
Ean8 = 2,
Upca = 4,
Upce = 8,
Code128 = 16, // 0x00000010
Code39 = 32, // 0x00000020
Code93 = 64, // 0x00000040
Interleaved2Of5 = 128, // 0x00000080
Qr = 256, // 0x00000100
DataMatrix = 512, // 0x00000200
Pdf417 = 1024, // 0x00000400
MsiPlessey = 2048, // 0x00000800
Gs1Databar = 4096, // 0x00001000
Gs1DatabarExpanded = 8192, // 0x00002000
Codabar = 16384, // 0x00004000
Aztec = 32768, // 0x00008000
TwoDigitAddOn = 65536, // 0x00010000
FiveDigitAddOn = 131072, // 0x00020000
MaxiCode = 262144, // 0x00040000
Code11 = 524288, // 0x00080000
Gs1DatabarLimited = 1048576, // 0x00100000
Code25 = 2097152, // 0x00200000
MicroPdf417 = 4194304, // 0x00400000
Rm4scc = 8388608, // 0x00800000
Kix = 16777216, // 0x01000000
DotCode = 33554432, // 0x02000000
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment