2

When I try to reuse the formatting of the currency format using a separate class an error is generated.

Main routine:

using Android.App;
using Android.OS;
using Android.Widget;

namespace TextWatcher
{
    [Activity(Label = "Main2", MainLauncher = true)]
    public class Main_Activity1 : Activity
    {
        private EditText editText;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Main);

            editText = FindViewById<EditText>(Resource.Id.editText);
            var watch = new CurrencyTextWatcher(editText);

            editText.AddTextChangedListener(watch);


        }
    }
}

Class that does the formatting (Better way to Format Currency Input editText?)

using Android.Widget;
using Android.Text;
using Java.Lang;
using System;
using Java.Text;
using Java.Util;
using System.Text.RegularExpressions;

namespace TextWatcher
{

    public class CurrencyTextWatcher : ITextWatcher
    {
        private EditText editText;
        private string lastAmount = "";
        private int lastCursorPosition = -1;

        public CurrencyTextWatcher(EditText txt)
        {
            this.editText = txt;
        }

        public IntPtr Handle
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public void AfterTextChanged(IEditable s)
        {

        }

        public void BeforeTextChanged(ICharSequence amount, int start, int count, int after)
        {
            string value = amount.ToString();
            if (!value.Equals(""))
            {
                string cleanString = clearCurrencyToNumber(value);
                string formattedAmount = transformtocurrency(cleanString);
                lastAmount = formattedAmount;
                lastCursorPosition = editText.SelectionStart;
            }
        }

        public void OnTextChanged(ICharSequence amount, int start, int before, int count)
        {
            if (!amount.ToString().Equals(lastAmount))
            {
                string cleanString = clearCurrencyToNumber(amount.ToString());
                try
                {
                    string formattedAmount = transformtocurrency(cleanString);
                    editText.RemoveTextChangedListener(this);
                    editText.Text = formattedAmount;
                    editText.SetSelection(formattedAmount.Length);
                    editText.AddTextChangedListener(this);

                    if (lastCursorPosition != lastAmount.Length && lastCursorPosition != -1)
                    {
                        int lengthDelta = formattedAmount.Length - lastAmount.Length;
                        int newCursorOffset = Java.Lang.Math.Max(0, Java.Lang.Math.Min(formattedAmount.Length, lastCursorPosition + lengthDelta));
                        editText.SetSelection(newCursorOffset);
                    }
                }
                catch (System.Exception e)
                {
                    //log something
                }
            }
        }

        public static string clearCurrencyToNumber(string currencyValue)
        {
            string result = "";

            if (currencyValue == null)
            {
                result = "";
            }
            else
            {
                result = Regex.Replace(currencyValue, "[^0-9]", "");
            }
            return result;
        }

        public static string transformtocurrency(string value)
        {
            double parsed = double.Parse(value);
            string formatted = NumberFormat.GetCurrencyInstance(new Locale("pt", "br")).Format((parsed / 100));
            formatted = formatted.Replace("[^(0-9)(.,)]", "");
            return formatted;
        }

        public static bool isCurrencyValue(string currencyValue, bool podeSerZero)
        {
            bool result;

            if (currencyValue == null || currencyValue.Length == 0)
            {
                result = false;
            }
            else
            {
                if (!podeSerZero && currencyValue.Equals("0,00"))
                {
                    result = false;
                }
                else
                {
                    result = true;
                }
            }
            return result;
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}

Once the code is executed, the error occurs, see the image below:

System.InvalidCastException: Specified cast is not valid on editText.AddTextChangedListener

Help!

Community
  • 1
  • 1

1 Answers1

1

Your TextWatcher implementation needs to inherit from a Java.Lang.Object in order for an Android Callable Wrappers (ACW) to be created so this object can across between the Java and .Net VMs.

Ref: Android Callable Wrappers

Since you are creating a standalone watcher, remove the Dispose and Handle from your current implementation (if needed, you will need to override them for the ones on Java.Lang.Object)

i.e.:

public class CurrencyTextWatcher : Java.Lang.Object, ITextWatcher
{

    public void AfterTextChanged(IEditable s)
    {
        //~~~~
    }

    public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
    {
        //~~~~
    }

    public void OnTextChanged(ICharSequence s, int start, int before, int count)
    {
        //~~~~
    }
}

Now you can instantiate and assign it as a text watcher listener:

SushiHangover
  • 73,120
  • 10
  • 106
  • 165