EditText - setText()方法不起作用 - StackOverFlow异常

时间:2014-03-17 14:35:56

标签: java android android-edittext

我有问题想弄清楚为什么我在这行代码上得到StackOverFlow Exception:

 mPassword.setText(phone);

我正在尝试在用户输入数字时格式化数字并获取格式化的数字并将其设置为EditText小部件。我该如何解决或解决这个问题?

以下是代码:

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Toast.makeText(getApplicationContext(), "In onTextChanged() Method", Toast.LENGTH_SHORT).show();
        if (s.length() != 0) {
            switch (et.getId()) {
            case R.id.etUsername: {

            }
            break;

            case R.id.etPassword: {
                phone = formatPhoneNumber(phone);
                Log.i("PHONE", "Phone NUMB IS:"+phone);
                mPassword.setText(phone);  //THE ERROR HAPPENS HERE
            }
            }
        }
    }             

public String formatPhoneNumber(String phoneNumber) {
    Toast.makeText(getApplicationContext(), "In formatPhoneNumber() Method", Toast.LENGTH_SHORT).show();
    final StringBuffer sbPhone = new StringBuffer(phoneNumber);

    if (sbPhone.length() == 9) {
        //phoneNumber.substring(8, '-');
        //phoneNumber.insert(8, '-');
        if (sbPhone.indexOf("-") == -1) {
            sbPhone.insert(8, "-");
        }
    }
    else if (sbPhone.length() == 8) {
        //phoneNumber.replace("-", "");
        if (sbPhone.indexOf("-") != -1) {
            sbPhone.delete(sbPhone.indexOf("-"), sbPhone.indexOf("-"));
        }
    }
 }

这是错误:

03-17 09:16:42.844: E/AndroidRuntime(22047): FATAL EXCEPTION: main
03-17 09:16:42.844: E/AndroidRuntime(22047): java.lang.StackOverflowError
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:913)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.TextUtils.getChars(TextUtils.java:81)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.method.ReplacementTransformationMethod$ReplacementCharSequence.getChars(ReplacementTransformationMethod.java:151)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.TextUtils.getChars(TextUtils.java:81)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.MeasuredText.setPara(MeasuredText.java:117)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.StaticLayout.generate(StaticLayout.java:264)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.DynamicLayout.reflow(DynamicLayout.java:324)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.text.DynamicLayout.<init>(DynamicLayout.java:174)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.makeSingleLayout(TextView.java:7106)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.makeNewLayout(TextView.java:6955)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.checkForRelayout(TextView.java:7551)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4410)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4222)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at com.example.edittexttest.MainActivity$InputValidator.onTextChanged(MainActivity.java:91)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.sendOnTextChanged(TextView.java:8430)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4413)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.TextView.setText(TextView.java:4247)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.EditText.setText(EditText.java:108)
03-17 09:16:42.844: E/AndroidRuntime(22047):    at android.widget.Text

任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:1)

我猜您无限调用onTextChanged方法,因为您在TextWatcher内设置文本会导致onTextChanged再次被调用。

答案 1 :(得分:1)

您需要更改正在使用的方法,因为每次致电:

mPassword.setText(phone);

这将触发onTextChanged处理程序,它将按照代码再次执行:mPassword.setText(phone);

以StackOverflow结尾。

编辑:一个快速修复可能是添加一个布尔标志,用作递归中的基本案例:

@Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Toast.makeText(getApplicationContext(), "In onTextChanged() Method", Toast.LENGTH_SHORT).show();
        if (s.length() != 0) {
            switch (et.getId()) {
            case R.id.etUsername: {

            }
            break;

            case R.id.etPassword: {
                if (flag){
                  flag = false;
                  return;
                }

                phone = formatPhoneNumber(phone);
                Log.i("PHONE", "Phone NUMB IS:"+phone);
                flag = true;  //number formatted!!!
                mPassword.setText(phone);  //THE ERROR HAPPENS HERE
            }
            }
        }
    }    

答案 2 :(得分:0)

问题出在TextWatcher上,当你使用setText时,它还会调用TextWatcher上的回调,这样一旦用户输入TextWatcher进入无限循环的东西,他就会不断地设置文本。

为了防止这种情况,对于所有情况,最简单但不是最好的解决方案是使用标志来确定回调来源的文本改变的位置。尝试这样的事情:

private boolean isUserCallback = true;

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    //Toast.makeText(getApplicationContext(), "In onTextChanged() Method", Toast.LENGTH_SHORT).show();
    if (s.length() != 0 && isUserCallback) {
        switch (et.getId()) {
            case R.id.etUsername: {

            }
            break;

            case R.id.etPassword: {
                phone = formatPhoneNumber(phone);
                Log.i("PHONE", "Phone NUMB IS:"+phone);
                mPassword.setText(phone);  //THE ERROR HAPPENS HERE
            }
        }
    } else {
        isUserCallback = true;
    }
} 

只有当isUserCallback为true时,才会对回调作出反应。如果以编程方式设置文本,则只需将布尔值设置为false:

this.isUserCallback = false;
mPassword.setText("asdf");

isUserCallback标志将在回调中自动重置。

答案 3 :(得分:0)

我最近遇到过这个问题。有时setText不适用于整数,您需要setText(phone+"")。这将有效。

答案 4 :(得分:0)

您可以在设置文本之前删除观察者,并在之后重置相同的观察者。

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    //Toast.makeText(getApplicationContext(), "In onTextChanged() Method", Toast.LENGTH_SHORT).show();
    if (s.length() != 0) {
        switch (et.getId()) {
        case R.id.etUsername: {

        }
        break;

        case R.id.etPassword: {
            mPassword.removeTextChangedListener(theWatcher);
            phone = formatPhoneNumber(phone);
            Log.i("PHONE", "Phone NUMB IS:"+phone);
            mPassword.setText(phone);  //THE ERROR HAPPENS HERE
            mPassword.addTextChangedListener(theWatcher); 
        }
        }
    }
} 

希望这有帮助。