簡體   English   中英

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

[英]EditText - setText() Method Not Working - StackOverFlow Exception

我有問題想弄清楚為什么我在這行代碼上得到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

任何幫助,將不勝感激!

我猜你是無限調用onTextChanged方法,因為你正在設置中的文本TextWatcher這將導致onTextChanged再次調用。

您需要更改正在使用的方法,因為每次調用時都會:

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
            }
            }
        }
    }    

通過調用setText來遞歸調用onTextChanged方法。 setText方法調用導致另一個onTextChanged觸發器,它會調用setText ,依此類推。 從代碼編輯TextField時嘗試設置標志,因此不會觸發其他更改。 例如:

private boolean autochange = false;

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if(autochange) { // skip execution if triggered by code
       autochange=false; // next change is not triggered by code
       return;
    }
    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);
            autochange=true;
            mPassword.setText(phone); 
        }
        }
    }
}   

問題在於你的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標志將在回調中自動重置。

我最近遇到過這個問題。 有時setText不能用整數,你需要setText(phone+"") 這會奏效。

您可以在設置文本之前刪除觀察者,然后重置相同的觀察者。

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

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM