StackOverflowError - 冗余调用onTextChanged

时间:2016-07-21 21:56:13

标签: android android-edittext stack-overflow textwatcher redundancy

(我正在学习英语......因此,原谅我)

我正在制作一个应用来转换bin,dec和hex。我有三个EditText(数字类型),我希望在其中一个树内容发生更改时执行某些操作。

我的三个EditText:

<EditText
    android:id="@+id/input1"
    android:inputType="number"
    android:digits="01"
    android:hint="BIN"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<EditText
    android:id="@+id/input2"
    android:inputType="number"
    android:digits="0123456789"
    android:hint="DEC"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<EditText
    android:id="@+id/input3"
    android:digits="0123456789ABCDEFabcdef"
    android:hint="HEX"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

所以我使用以下代码来处理文本更改:

EditText input1 = (EditText) findViewById(R.id.input1);
EditText input2 = (EditText) findViewById(R.id.input2);
EditText input3 = (EditText) findViewById(R.id.input3);

input1.addTextChangedListener(new TextWatcher() {

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

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

            String bin = input1.getText().toString();
            String s1 = binToDec(bin) + "";
            String s2 = binToHex(bin);
            input2.setText(s1);
            input3.setText(s2);
        }

        public void afterTextChanged(Editable s) {}
    });

    input2.addTextChangedListener(new TextWatcher() {

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            try{
                String dec = input2.getText().toString();
                int num = Integer.parseInt(dec);

                input1.setText(decToBin(num));
                input3.setText(decToHex(num));
            }
            catch (NumberFormatException nfe){

            }
        }

        public void afterTextChanged(Editable s) {}
    });

    input3.addTextChangedListener(new TextWatcher() {

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

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

            String hex = input3.getText().toString();
            input1.setText(hexToBin(hex));
            input2.setText(hexToDec(hex) + "");
        }

        public void afterTextChanged(Editable s) {}
    });

但是......例如,每当用户输入edittext 1时,edittext 2和3的内容都会发生变化。它导致另一个调用onTextChanged,然后调用无限堆栈调用(StackOverflow)。 所以...有没有更好的方法来做我想要的? 有谁可以帮助我吗? 谢谢!!!

2 个答案:

答案 0 :(得分:1)

我建议用户输入文字后按一下按钮,而不是使用TextChangedListener。这消除了对onTextChange的无限调用。该按钮可以检查用户输入的号码,并可以相应地更改另一个EditTexts

答案 1 :(得分:0)

这是我的建议(我得到的第一个想法): 声明三个布尔editingInput1editingInput2editingInput3最初设置为false

现在设置EditText(例如input1)的文本,将其布尔值设置为true(editingInput1 = true),并将onTextChanged设置为input1你测试editingInput1==true,如果是这种情况(这意味着这个调用是.setText(...)而不是用户输入的结果)你将布尔值重置为false然后你返回从方法。

这是您的代码的样子:

EditText input1 = (EditText) findViewById(R.id.input1);
EditText input2 = (EditText) findViewById(R.id.input2);
EditText input3 = (EditText) findViewById(R.id.input3);

boolean editingInput1= false, editingInput2= false, editingInput3= false;

input1.addTextChangedListener(new TextWatcher() {

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(editingInput1){
            editingInput1= false;
            return;
        }
        String bin = input1.getText().toString();
        String s1 = binToDec(bin) + "";
        String s2 = binToHex(bin);
        editingInput2= true; //it must be set to true befor calling .setText(...)
        input2.setText(s1); 
        editingInput3 = true;
        input3.setText(s2);
    }

    public void afterTextChanged(Editable s) {}
});

input2.addTextChangedListener(new TextWatcher() {

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(editingInput2){
            editingInput2= false;
            return;
        }
        try{
            String dec = input2.getText().toString();
            int num = Integer.parseInt(dec);

            editingInput1 = true;
            input1.setText(decToBin(num));
            editingInput3 = true;
            input3.setText(decToHex(num));
        }
        catch (NumberFormatException nfe){

        }
    }

    public void afterTextChanged(Editable s) {}
});

input3.addTextChangedListener(new TextWatcher() {

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(editingInput3){
            editingInput3= false;
            return;
        }
        String hex = input3.getText().toString();

        editingInput1 = true;
        input1.setText(hexToBin(hex));
        editingInput2 = true;
        input2.setText(hexToDec(hex) + "");
    }

    public void afterTextChanged(Editable s) {}
});