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

标签 android xamarin android-edittext xamarin.android

当我尝试使用单独的类重用货币格式的格式时,会生成错误。

主要程序:

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);


        }
    }
}

执行格式化的类 ( 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();
        }
    }
}

代码执行后出现错误,如下图:

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

帮助!

最佳答案

您的 TextWatcher 实现需要从 Java.Lang.Object 继承,以便创建 Android Callable Wrappers (ACW),以便此对象可以 跨越 Java 和 .Net VM。

引用:Android Callable Wrappers

由于您正在创建一个独立的观察者,因此从您当前的实现中删除 DisposeHandle(如果需要,您将需要覆盖它们用于 Java.Lang.Object)

即:

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)
    {
        //~~~~
    }
}

现在您可以将其实例化并指定为文本观察器监听器:

关于android - System.InvalidCastException : Specified cast is not valid on editText. AddTextChangedListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42166202/

相关文章:

android - 使用 MVP 模型编写 "login"App 时出现问题

java - 如何通过同一网络的 Android(就像 Gmote 2.0 所做的那样)在计算机上播放 mp3 文件?

xamarin - 为什么 Xamarin.Forms 应用无法在 Chromebook 上运行?

android - 将 EditText 的 InputType 设置为 TYPE_NULL 后无法更改

android - setIcon(ic_menu_more) 没有效果

c# - 将 XAML 中的按钮可见性绑定(bind)到 View 模型?

c# - 可以在 Xamarin Forms 中使用的汉堡包/抽屉下拉菜单?

android - 为什么模拟器虚拟键盘上的某些字母在输入类型为 "number"的 Android EditText 中显示数字?

android - ListView 的搜索功能

android - 什么是工具 :layout_constraintBaseline_creator attribute in ConstraintLayout?