Skip to content

Instantly share code, notes, and snippets.

@akaegi
Created March 18, 2021 10:39
Show Gist options
  • Save akaegi/756fb23af01cfaf5beffc99035f91d17 to your computer and use it in GitHub Desktop.
Save akaegi/756fb23af01cfaf5beffc99035f91d17 to your computer and use it in GitHub Desktop.
NumberWithUnitPicker
using AiForms.Renderers;
using Xamarin.Forms;
namespace AiForms.Renderers
{
public class NumberWithUnitPickerCell: NumberPickerCell
{
public static BindableProperty UnitProperty = BindableProperty.Create(nameof (Unit), typeof (string), typeof (NumberWithUnitPickerCell), "", BindingMode.TwoWay);
public string Unit
{
get => (string) this.GetValue(UnitProperty);
set => this.SetValue(UnitProperty, value);
}
}
}
using System;
using AiForms.Renderers;
using AiForms.Renderers.Droid;
using Android.Content;
using Android.Runtime;
using Android.Text;
using Android.Widget;
using Java.Lang;
using Java.Lang.Reflect;
using Xamarin.Forms;
using APicker = Android.Widget.NumberPicker;
using Exception = System.Exception;
using Object = Java.Lang.Object;
using String = System.String;
[assembly: ExportRenderer(typeof(NumberWithUnitPickerCell), typeof(NumberWithUnitPickerCellRenderer))]
namespace AiForms.Renderers.Droid
{
[Android.Runtime.Preserve(AllMembers = true)]
public class NumberWithUnitPickerCellRenderer : CellBaseRenderer<NumberWithUnitPickerCellView> { }
/// <summary>
/// Number picker cell view.
/// </summary>
[Android.Runtime.Preserve(AllMembers = true)]
public class NumberWithUnitPickerCellView : NumberPickerCellView
{
public NumberWithUnitPickerCellView(Context context, Cell cell)
: base(context, cell)
{
}
public NumberWithUnitPickerCellView(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
NumberWithUnitPickerCell _NumberPickerCell => Cell as NumberWithUnitPickerCell;
protected override string FormatNumber(int? number)
{
return number.HasValue && !String.IsNullOrEmpty(_NumberPickerCell.Unit)
? $"{number} {_NumberPickerCell.Unit}"
: number?.ToString() ?? "";
}
protected override void OnPickerCreated(NumberPicker picker)
{
base.OnPickerCreated(picker);
if (!String.IsNullOrEmpty(_NumberPickerCell.Unit))
{
picker.SetFormatter(new UnitFormatter(_NumberPickerCell.Unit));
ApplyInitialFormattingBugfix(picker);
}
}
// see bug https://stackoverflow.com/questions/17708325/android-numberpicker-with-formatter-doesnt-format-on-first-rendering/54083214#54083214
// and https://issuetracker.google.com/issues/36952035
private void ApplyInitialFormattingBugfix(NumberPicker picker)
{
try
{
Class klass = Java.Lang.Class.FromType(typeof(NumberPicker));
Field f = klass.GetDeclaredField("mInputText");
f.Accessible = true;
EditText inputText = (EditText) f.Get(picker);
inputText.SetFilters(new IInputFilter[0]);
}
catch (Exception)
{
// silently ignore this
}
}
}
internal class UnitFormatter : Object, NumberPicker.IFormatter
{
private readonly string _unit;
public UnitFormatter(string unit)
{
_unit = unit;
}
public string Format(int value)
{
return value + " " + _unit;
}
}
}
using System;
using AiForms.Renderers;
using AiForms.Renderers.iOS;
using UIKit;
using Xamarin.Forms;
using XFSpike.iOS;
[assembly: ExportRenderer(typeof(NumberWithUnitPickerCell), typeof(NumberWithUnitPickerCellRenderer))]
namespace XFSpike.iOS
{
[Foundation.Preserve(AllMembers = true)]
public class NumberWithUnitPickerCellRenderer : CellBaseRenderer<NumberWithUnitPickerCellView> { }
[Foundation.Preserve(AllMembers = true)]
public class NumberWithUnitPickerCellView : NumberPickerCellView
{
public NumberWithUnitPickerCellView(Cell formsCell) : base(formsCell)
{
}
NumberWithUnitPickerCell _NumberPickerCell => Cell as NumberWithUnitPickerCell;
protected override string FormatNumber(int? number)
{
return number.HasValue && !String.IsNullOrEmpty(_NumberPickerCell.Unit)
? $"{number} {_NumberPickerCell.Unit}"
: number?.ToString() ?? "";
}
protected override NumberPickerSource CreateNumberPickerSource()
{
return new NumberWithUnitPickerSource(_NumberPickerCell.Unit);
}
}
[Foundation.Preserve(AllMembers = true)]
internal class NumberWithUnitPickerSource : NumberPickerSource
{
private readonly string _unit;
public NumberWithUnitPickerSource(string unit)
{
_unit = unit;
}
public override string GetTitle(UIPickerView picker, nint row, nint component)
{
int number = Items[(int)row];
return String.IsNullOrEmpty(_unit)
? number.ToString()
: $"{number} {_unit}";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment