Search code examples
androidcputextwatchertextchanged

onTextChanged event doesn't work in Android


I have an EditBox and a TextView in an application. I want the TextView to convert numbers that I type into the EditBox to words as I'm typing ( onTextChanged() ) and show it. I made the class for converting numbers to words and it works correctly. I search for onTextChanged event and I found how to use it but I faced a problem.

Here is the code:

ed.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        try {

            String num = ed.getText().toString();
            String str = num.replace(",", "");
            double x = Double.parseDouble(str);
            String text = NumberFormat.getIntegerInstance(Locale.US).format(x);

            ed.setText(text);

            /*if (ed.length() != 0)
            {
                String numtoalph = NumToAlph.convert(x);
                tv.setText( numtoalph + tv.getText().toString());
            }*/

            NumToAlph numToAlph = new NumToAlph();
            String alph = NumToAlph.Convert(text, x);
            tv.setText(alph + " ریال");

        }
        catch (Exception ex)
        {
            tv.setText(ex.toString());
        }


        @Override
        public void afterTextChanged(Editable s) {}

});

*NumToAlph is the class

When I installed it on my phone and tried to type as I pressed the first button the app froze and after a minute I got a notification which said that

this app is using too much CPU

I tested the code, I mean this

try {

    String num = ed.getText().toString();
    String str = num.replace(",", "");
    double x = Double.parseDouble(str);
    String text = NumberFormat.getIntegerInstance(Locale.US).format(x);

    ed.setText(text);
    /*
    if (ed.length() != 0)
    {
        String numtoalph = NumToAlph.convert(x);
        tv.setText( numtoalph + tv.getText().toString());
    }
    */

    NumToAlph numToAlph = new NumToAlph();
    String alph = NumToAlph.Convert(text, x);
    tv.setText(alph + " ریال");
}
catch (Exception ex)
{
    tv.setText(ex.toString());
}

in a button click event and it worked fast and correctly. Does any one have an idea about this problem?

I have programmed this app for windows in C# before, and used this for textChanged event with no problems:

decimal Number;
if (decimal.TryParse(textBox1.Text, out Number))
{
    textBox1.Text = string.Format("{0:N0}", Number);
    textBox1.SelectionStart = textBox1.Text.Length;
}

try
{
    NumToAlph dd = new NumToAlph();
    string x = textBox1.Text.Replace(",", "").ToString();
    textBox2.Text = dd.num2str(x) + " ریال";
}
catch (Exception ex)
{
    MessageBox.Show("Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Solution

  • Maybe this helps:

    if (!isChangedProgramatically) {
        String num = editText.getText().toString();
        if(!num.isEmpty()) {
            String str = num.replace(",", "");
            double x = Double.parseDouble(str);
            String text = NumberFormat.getIntegerInstance(Locale.US).format(x);
    
            isChangedProgramatically = true;
            editText.setText(text);
        }
    } else {
        editText.setSelection(editText.getText().length());
        isChangedProgramatically = false;
    }
    

    isChangedProgramatically is a private boolean (default false) of your Activity.