Android Numeric Keyboard, Samsung Galaxy, no decimals

I just realized that the numeric keyboard type for Xamarin entry's ignores "." completely even if present on the keyboard, it doesn't even fire the text_changed event. Android on Samsung Galaxy phones have completely removed the option of "," and only has "." this makes users of my app on Samsung Galaxy phones unable to write decimals in the entry since they have no available seperator. Right now I can change it to a ordinary keyboard and write logic only allowing number inputs which I really dislike.

Does any1 have any suggestions for solutions to this issue?

Thanks in advance for anyone reading this :)

Best Answer

  • edited October 14 Accepted Answer

    Thanks for your input @LeonLu

    for anyone looking at this issue, I ended up creating a custom renderer for Xamarins Entry, where on android i set the falgs myself to:

    Android.Text.InputTypes its = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagSigned | Android.Text.InputTypes.NumberFlagDecimal; Control.SetRawInputType(its);

    This way i get around Xamarins logic when appliyin the "Numeric" keyboard that ignores key pressed event when the seperator is not part of the current cultures seperator style, e.g. if you're in (english, US) it ignores ',' and if in (english UK) it ignores '.'. This became and issue on Samsung Galaxy phones since they regardless of culture only have the '.' sign.

    Once i have the Key event firing the Text changed then i could in my entry write logic making sure that I myself applied the correct seperator and removed any wrong characters in the entry:

    `
    private void CustomDecimalEntry_TextChanged(object sender, TextChangedEventArgs e)
    {

      var entry = (Entry)sender;
      entry.TextChanged -= CustomDecimalEntry_TextChanged;
      try
      {
              char[] allowedChars = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ',', '.' };               
              if (e.NewTextValue?.Length - e.NewTextValue?.Replace(".", string.Empty).Replace(",", string.Empty).Length == 1)
              {
              CustomDecimalEntry.Text = e.NewTextValue.Replace(".", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator).Replace(",", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
              }
              else if (e.NewTextValue?.Length - e.NewTextValue?.Replace(".", string.Empty).Replace(",", string.Empty).Length > 1)
              {
                        CustomDecimalEntry.Text = e.OldTextValue;
               }
    
               foreach (char x in CustomDecimalEntry.Text)
              {
                   if (!allowedChars.Contains(x))
                   {
                       CustomDecimalEntry.Text = e.OldTextValue;
                       break;
                   }
              }
        }
        finally
        {
              entry.TextChanged += CustomDecimalEntry_TextChanged;
        }
     }`
    

    Finally to make sure i didnt have to do this on iOS i simply keept the Xamarin logic for entries by applying their keyboard only on iOS devices.

        <OnPlatform x:TypeArguments="Keyboard">
            <On Platform="iOS" Value="Numeric"/>
        </OnPlatform>
    

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    You can make a custom renderer entry then only allowing number inputs(Did you used Control.InputType = InputTypes.NumberFlagDecimal; to acheieve that? ), you can used this custom renderer entry at need place.

    Compare this way and custom a keyboard, I think your method is much better.

  • XamarinProblemsXamarinProblems Member ✭✭

    Hello @LeonLu What is have is

    <Entry Keyboard="Numeric" Text={Binding Value}/>

    But Xamarins numeric keyboard ignores the '.' key if its there and keeps ignoring it even if the ',' key isn't there. Which means the keyboard cant make decimals on the Samsung Galaxy keyboards which only have '.'.

    I guess I'll have to make a custom rendere for numerical inputs instead of of using Xamarins own link below

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    You can refer to this thread, you can create a custom Entry with a Custom keyborad in your application.
    https://medium.com/swlh/how-to-create-a-custom-keyboard-with-xamarin-forms-android-4fa3b83dad1d

  • XamarinProblemsXamarinProblems Member ✭✭
    edited October 14 Accepted Answer

    Thanks for your input @LeonLu

    for anyone looking at this issue, I ended up creating a custom renderer for Xamarins Entry, where on android i set the falgs myself to:

    Android.Text.InputTypes its = Android.Text.InputTypes.ClassNumber | Android.Text.InputTypes.NumberFlagSigned | Android.Text.InputTypes.NumberFlagDecimal; Control.SetRawInputType(its);

    This way i get around Xamarins logic when appliyin the "Numeric" keyboard that ignores key pressed event when the seperator is not part of the current cultures seperator style, e.g. if you're in (english, US) it ignores ',' and if in (english UK) it ignores '.'. This became and issue on Samsung Galaxy phones since they regardless of culture only have the '.' sign.

    Once i have the Key event firing the Text changed then i could in my entry write logic making sure that I myself applied the correct seperator and removed any wrong characters in the entry:

    `
    private void CustomDecimalEntry_TextChanged(object sender, TextChangedEventArgs e)
    {

      var entry = (Entry)sender;
      entry.TextChanged -= CustomDecimalEntry_TextChanged;
      try
      {
              char[] allowedChars = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ',', '.' };               
              if (e.NewTextValue?.Length - e.NewTextValue?.Replace(".", string.Empty).Replace(",", string.Empty).Length == 1)
              {
              CustomDecimalEntry.Text = e.NewTextValue.Replace(".", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator).Replace(",", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
              }
              else if (e.NewTextValue?.Length - e.NewTextValue?.Replace(".", string.Empty).Replace(",", string.Empty).Length > 1)
              {
                        CustomDecimalEntry.Text = e.OldTextValue;
               }
    
               foreach (char x in CustomDecimalEntry.Text)
              {
                   if (!allowedChars.Contains(x))
                   {
                       CustomDecimalEntry.Text = e.OldTextValue;
                       break;
                   }
              }
        }
        finally
        {
              entry.TextChanged += CustomDecimalEntry_TextChanged;
        }
     }`
    

    Finally to make sure i didnt have to do this on iOS i simply keept the Xamarin logic for entries by applying their keyboard only on iOS devices.

        <OnPlatform x:TypeArguments="Keyboard">
            <On Platform="iOS" Value="Numeric"/>
        </OnPlatform>
    
Sign In or Register to comment.