Repository: dotnet/maui
File: src/Core/src/Platform/Android/LocalizedDigitsKeyListener.cs (C#)

Code before:
﻿using System.Collections.Generic;
using System.Globalization;
using Android.Text;
using Android.Text.Method;
using Java.Lang;
using Java.Text;

namespace Microsoft.Maui.Platform
{
	public class LocalizedDigitsKeyListener : NumberKeyListener
	{
		readonly char _decimalSeparator;

		// I'm not aware of a situation/locale where this would need to be something different, 
		// but we'll make it easy to localize the sign in the future just in case
		const char SignCharacter = '-';

		static Dictionary<char, LocalizedDigitsKeyListener>? UnsignedCache;
		static Dictionary<char, LocalizedDigitsKeyListener>? SignedCache;

		static char GetDecimalSeparator()
		{
			if (!(NumberFormat.Instance is DecimalFormat))
				return '.';

			string symbol = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
			return symbol == string.Empty ? '.' : symbol[0];
		}

		public static NumberKeyListener Create(InputTypes inputTypes)
		{
			if ((inputTypes & InputTypes.NumberFlagDecimal) == 0)
			{
				// If decimal isn't allowed, we can just use the Android version
#pragma warning disable CS0618, CA1416, CA1422 // Deprecated in API 26: https://developer.android.com/reference/android/text/method/DigitsKeyListener#getInstance(boolean,%20boolean)
				return DigitsKeyListener.GetInstance(inputTypes.HasFlag(InputTypes.NumberFlagSigned), false);
#pragma warning restore CS0618, CA1416, CA1422
			}

			// Figure out what the decimal separator is for the current locale
			char decimalSeparator = GetDecimalSeparator();

			if (decimalSeparator == '.')
			{
				// If it's '.', then we can just use the default Android version
#pragma warning disable CS0618, CA1416, CA1422 // Deprecated in API 26: https://developer.android.com/reference/android/text/method/DigitsKeyListener#getInstance(boolean,%20boolean)
				return DigitsKeyListener.GetInstance(inputTypes.HasFlag(InputTypes.NumberFlagSigned), true);
#pragma warning restore CS0618, CA1416, CA1422

Review comment (bug):
This whole change is scary. It says in the android docs:

> To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance().

So is that wrong? The thing is not localized?

What is the value for the locales that are using a comma?

If this whole thing is not needed, then we may as well just delete this if block. Is NumberFormat.Instance ever null?

Code after:
﻿using System.Collections.Generic;
using System.Globalization;
using Android.Text;
using Android.Text.Method;
using Java.Lang;
using Java.Text;

namespace Microsoft.Maui.Platform
{
	public class LocalizedDigitsKeyListener : NumberKeyListener
	{
		readonly char _decimalSeparator;

		// I'm not aware of a situation/locale where this would need to be something different, 
		// but we'll make it easy to localize the sign in the future just in case
		const char SignCharacter = '-';

		static Dictionary<char, LocalizedDigitsKeyListener>? UnsignedCache;
		static Dictionary<char, LocalizedDigitsKeyListener>? SignedCache;

		public static NumberKeyListener Create(InputTypes inputTypes)
		{
			if ((inputTypes & InputTypes.NumberFlagDecimal) == 0)
			{
				// If decimal isn't allowed, we can just use the Android version
#pragma warning disable CS0618, CA1416, CA1422 // Deprecated in API 26: https://developer.android.com/reference/android/text/method/DigitsKeyListener#getInstance(boolean,%20boolean)
				return DigitsKeyListener.GetInstance(inputTypes.HasFlag(InputTypes.NumberFlagSigned), false);
#pragma warning restore CS0618, CA1416, CA1422
			}

			// Figure out what the decimal separator is for the current locale
			var symbol = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
			var decimalSeparator = string.IsNullOrEmpty(symbol) ? '.' : symbol[0];

			if (decimalSeparator == '.')
			{
				// If it's '.', then we can just use the default Android version
#pragma warning disable CS0618, CA1416, CA1422 // Deprecated in API 26: https://developer.android.com/reference/android/text/method/DigitsKeyListener#getInstance(boolean,%20boolean)
				return DigitsKeyListener.GetInstance(inputTypes.HasFlag(InputTypes.NumberFlagSigned), true);
#pragma warning restore CS0618, CA1416, CA1422
			}

			// If decimals are enabled and the locale's decimal separator is not '.'
			// (which is hard-coded in the Android DigitKeyListener), then use 
			// our custom one with a configurable decimal separator
			return GetInstance(inputTypes, decimalSeparator);
		}