Textwatcher给人错误#1 [英] Textwatcher giving Stackoverflow error

查看:121
本文介绍了Textwatcher给人错误#1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提出它采用TextWatcher长度转换器。
缩短code是

  v1.addTextChangedListener(新TextWatcher(){         @覆盖
            公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数后INT){
            }
            @覆盖
            公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
                VAL1 = Double.parseDouble(v1.getText()的toString());
                将val2 = InchToCm(VAL1);
                VAL3 = InchToMl(VAL1);
                VAL4 = InchToKm(VAL1);
                val5 = InchToM(VAL1);
                VAL6 = InchToY(VAL1);
                val7 = InchToFt(VAL1);
                的Val8 = InchToLg(VAL1);
                val9 = InchToLgn(VAL1);
                VAl11难= InchTomm(VAL1);
                val12 = InchToNm(VAL1);
                V2。的setText(Double.toString(val2中));
                V3。的setText(Double.toString(VAL3));
                V4。的setText(Double.toString(VAL4));
                V5。的setText(Double.toString(val5));
                V6。的setText(Double.toString(VAL6));
                V7。的setText(Double.toString(val7));
                V8。的setText(Double.toString(的Val8));
                V9。的setText(Double.toString(val9));
                V11。的setText(Double.toString(VAl11难));
                V12。的setText(Double.toString(val12));            }            @覆盖
            公共无效afterTextChanged(编辑S){            }
        });
     v2.addTextChangedListener(新TextWatcher(){         @覆盖
            公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数后INT){
            }
            @覆盖
            公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
                将val2 = Double.parseDouble(v2.getText()的toString());
                VAL1 = CmToInch(val2的);
                VAL3 = CmToMl(val2的);
                VAL4 = CmToKm(val2的);
                val5 = CmToM(val2的);
                VAL6 = CmToY(val2的);
                val7 = CmToFt(val2的);
                的Val8 = CmToLg(val2的);
                val9 = CmToLgn(val2的);
                VAl11难= CmTomm(val2的);
                val12 = CmToNm(val2的);                V1。的setText(Double.toString(VAL1));
                V3。的setText(Double.toString(VAL3));
                V4。的setText(Double.toString(VAL4));
                V5。的setText(Double.toString(val5));
                V6。的setText(Double.toString(VAL6));
                V7。的setText(Double.toString(val7));
                V8。的setText(Double.toString(的Val8));
                V9。的setText(Double.toString(val9));
                V11。的setText(Double.toString(VAl11难));
                V12。的setText(Double.toString(val12));            }            @覆盖
            公共无效afterTextChanged(编辑S){            }
        });

我得到一个计算器error.if我删除textwatcher code为V2 completely.the文本观察家对V1完美的作品..
我只是希望所有我的EditText与textwatcher工作。
我想什么?和我应该怎么改变?

继承人的logcat的

  20 08-20:31:28.122:E / AndroidRuntime(30377):致命异常:主要
08-20 20:31:28.122:E / AndroidRuntime(30377):java.lang.StackOverflowError
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.text.TextUtils.getChars(TextUtils.java:77)
08-20 20:31:28.122:E / AndroidRuntime(30377):android.text.TextUtils.indexOf(TextUtils.java:110)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.text.StaticLayout.generate(StaticLayout.java:182)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.text.DynamicLayout.reflow(DynamicLayout.java:284)
。08-20 20:31:28.122:E / AndroidRuntime(30377):在android.text.DynamicLayout<&初始化GT;(DynamicLayout.java:170)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.makeSingleLayout(TextView.java:6078)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.makeNewLayout(TextView.java:5976)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.checkForRelayout(TextView.java:6515)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3787)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3645)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.EditText.setText(EditText.java:80)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3620)
08-20 20:31:28.122:E / AndroidRuntime(30377):在com.tdx.simplelegthconverter.MainActivity $ 1.onTextChanged(MainActivity.java:55)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.sendOnTextChanged(TextView.java:7338)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3790)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3645)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.EditText.setText(EditText.java:80)
08-20 20:31:28.122:E / AndroidRuntime(30377):在android.widget.TextView.setText(TextView.java:3620)
08-20 20:31:28.122:E / AndroidRuntime(30377):在com.tdx.simplelegthconverter.MainActivity $ 2.onTextChanged(MainActivity.java:95)


解决方案

您正在创建V1和V2之间的文本变化无限循环。

每当你编辑V1的东西,它是 TextWatcher 设置V2的文本从而触发 onTextChanged()您V2的的 TextWatcher 。现在,V2的 TextWatcher 设置V1的文本(这会触发 onTextChanged()您V1再次)。这是创造一个永无止境的循环,你所得到的计算器例外。

您必须改变你的code的流量。

编辑:
我显示一个例子,如何获得两个领域的EditText摆脱StackOverflow上的错误。您可以按照尽可能多的EditTexts类似的编码,只要你想。

首先,你可以扩展这样的TextWatcher(这将帮助你保持你的code有组织而且,你可以用你所有的EditTexts同样TextWatcher):

 类MyInputWatcher实现TextWatcher {
        私人的EditText等;        私人MyInputWatcher(EditText上EDITTEXT){
            等= EDITTEXT;
        }        @覆盖
        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,
                INT后){        }        @覆盖
        公共无效之前onTextChanged(CharSequence中,诠释开始,诠释,
                诠释计数){            开关(et.getId()){
            案例R.id.editText1:{
                v2.removeTextChangedListener(watcher2);
                v2.setText(S);任何文字你想在editText2设置//设置
                v2.addTextChangedListener(watcher2);
                //添加上面的3条线code其他EditTexts,太(如果有的话)
                打破;
            }
            案例R.id.editText2:{
                v1.removeTextChangedListener(watcher1);
                v1.setText(多个); //你想在editText1设定集的任何文字
                v1.addTextChangedListener(watcher1);                打破;
            }
            }
        }        @覆盖
        公共无效afterTextChanged(编辑S){        }
    }

关键是要去除onTextChangeListeners你打电话之前的setText()。而且,然后重新添加这些用文字设置完成后。

声明这些成员变量:

 私人的EditText V1,V2;
私人MyInputWatcher watcher1,watcher2;

现在,在onCreate()方法,实现这个:

  V1 =(EditText上)findViewById(R.id.editText1);
V2 =(EditText上)findViewById(R.id.editText2);watcher1 =新MyInputWatcher(V1);
watcher2 =新MyInputWatcher(V2);v1.addTextChangedListener(watcher1);
v2.addTextChangedListener(watcher2);

为了您的方便,整个活动类看起来是这样的:

 进口android.os.Bundle;
进口android.support.v7.app.ActionBarActivity;
进口android.text.Editable;
进口android.text.TextWatcher;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.widget.EditText;公共类MainActivity扩展ActionBarActivity {    的EditText V1,V2;
    私人MyInputWatcher watcher1,watcher2;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        V1 =(EditText上)findViewById(R.id.editText1);
        V2 =(EditText上)findViewById(R.id.editText2);        watcher1 =新MyInputWatcher(V1);
        watcher2 =新MyInputWatcher(V2);        v1.addTextChangedListener(watcher1);
        v2.addTextChangedListener(watcher2);
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        INT ID = item.getItemId();
        如果(ID == R.id.action_settings){
            返回true;
        }
        返回super.onOptionsItemSelected(项目);
    }    类MyInputWatcher实现TextWatcher {
        私人的EditText等;        私人MyInputWatcher(EditText上EDITTEXT){
            等= EDITTEXT;
        }        @覆盖
        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,
                INT后){        }        @覆盖
        公共无效之前onTextChanged(CharSequence中,诠释开始,诠释,
                诠释计数){            开关(et.getId()){
            案例R.id.editText1:{
                v2.removeTextChangedListener(watcher2);
                v2.setText(S);任何文字你想在editText2设置//设置
                v2.addTextChangedListener(watcher2);
                打破;
            }
            案例R.id.editText2:{
                v1.removeTextChangedListener(watcher1);
                v1.setText(多个); //你想在editText1设定集的任何文字
                v1.addTextChangedListener(watcher1);                打破;
            }
            }
        }        @覆盖
        公共无效afterTextChanged(编辑S){        }
    }
}

i am making a length converter which uses TextWatcher. the shortened code is

 v1.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) {
                val1=Double.parseDouble(v1.getText().toString()); 
                val2=InchToCm(val1); 
                val3=InchToMl(val1);
                val4=InchToKm(val1);
                val5=InchToM(val1);
                val6=InchToY(val1);
                val7=InchToFt(val1);
                val8=InchToLg(val1);
                val9=InchToLgn(val1);
                val11=InchTomm(val1);
                val12=InchToNm(val1);


                v2. setText(Double.toString(val2)); 
                v3. setText(Double.toString(val3)); 
                v4. setText(Double.toString(val4)); 
                v5. setText(Double.toString(val5)); 
                v6. setText(Double.toString(val6)); 
                v7. setText(Double.toString(val7)); 
                v8. setText(Double.toString(val8));
                v9. setText(Double.toString(val9)); 
                v11. setText(Double.toString(val11)); 
                v12. setText(Double.toString(val12));

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
     v2.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) {
                val2=Double.parseDouble(v2.getText().toString()); 
                val1=CmToInch(val2);
                val3=CmToMl(val2);
                val4=CmToKm(val2);
                val5=CmToM(val2);
                val6=CmToY(val2);
                val7=CmToFt(val2);
                val8=CmToLg(val2);
                val9=CmToLgn(val2);
                val11=CmTomm(val2);
                val12=CmToNm(val2);

                v1. setText(Double.toString(val1)); 
                v3. setText(Double.toString(val3)); 
                v4. setText(Double.toString(val4)); 
                v5. setText(Double.toString(val5)); 
                v6. setText(Double.toString(val6)); 
                v7. setText(Double.toString(val7)); 
                v8. setText(Double.toString(val8));
                v9. setText(Double.toString(val9)); 
                v11. setText(Double.toString(val11)); 
                v12. setText(Double.toString(val12));

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

i am getting a stackoverflow error.if i remove the textwatcher code for v2 completely.the text watcher for v1 works perfectly.. i just want all my edittext to work with textwatcher. what am i missing?and what should i change?

heres the logcat

08-20 20:31:28.122: E/AndroidRuntime(30377): FATAL EXCEPTION: main
08-20 20:31:28.122: E/AndroidRuntime(30377): java.lang.StackOverflowError
08-20 20:31:28.122: E/AndroidRuntime(30377):    at           android.text.TextUtils.getChars(TextUtils.java:77)
08-20 20:31:28.122: E/AndroidRuntime(30377): android.text.TextUtils.indexOf(TextUtils.java:110)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at     android.text.StaticLayout.generate(StaticLayout.java:182)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.text.DynamicLayout.reflow(DynamicLayout.java:284)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.text.DynamicLayout.<init>(DynamicLayout.java:170)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.makeSingleLayout(TextView.java:6078)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.makeNewLayout(TextView.java:5976)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.checkForRelayout(TextView.java:6515)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3787)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3645)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.EditText.setText(EditText.java:80)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3620)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at com.tdx.simplelegthconverter.MainActivity$1.onTextChanged(MainActivity.java:55)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.sendOnTextChanged(TextView.java:7338)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3790)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3645)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.EditText.setText(EditText.java:80)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at android.widget.TextView.setText(TextView.java:3620)
08-20 20:31:28.122: E/AndroidRuntime(30377):    at   com.tdx.simplelegthconverter.MainActivity$2.onTextChanged(MainActivity.java:95)

解决方案

You are creating an infinite loop of Text Changes between v1 and v2.

Whenever you edit something in v1, it's TextWatcher sets the text of v2 which in turn triggers the onTextChanged() of your v2's TextWatcher. Now, v2's TextWatcher sets text of v1 (which triggers the onTextChanged() of your v1 again). This is creating a never-ending loop and you are getting the StackOverflow exception.

You have to change the flow of your code.

EDIT: I am showing an example, how to get rid of the StackOverflow error for two EditText fields. You can follow the similar coding for as many EditTexts as you want.

First of all, you can extend the TextWatcher like this (This will help you to keep your code organized. And, you can use this same TextWatcher for all your EditTexts):

class MyInputWatcher implements TextWatcher {
        private EditText et;

        private MyInputWatcher(EditText editText) {
            et = editText;
        }

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

        }

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

            switch (et.getId()) {
            case R.id.editText1: {
                v2.removeTextChangedListener(watcher2);
                v2.setText(s);// set whatever text you want to set in editText2
                v2.addTextChangedListener(watcher2);
                //add the above 3 lines of code for other EditTexts, too (if any)
                break;
            }
            case R.id.editText2: {
                v1.removeTextChangedListener(watcher1);
                v1.setText(s); // set whatever text you want to set in editText1
                v1.addTextChangedListener(watcher1);

                break;
            }
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    }

The trick is to remove the onTextChangeListeners before you call setText(). And, then add them back after you are done with setting text.

Declare these member variables:

private EditText v1, v2;
private MyInputWatcher watcher1, watcher2;

Now, in the onCreate() method, implement this:

v1 = (EditText)findViewById(R.id.editText1);
v2 = (EditText)findViewById(R.id.editText2);

watcher1 = new MyInputWatcher(v1);
watcher2 = new MyInputWatcher(v2);

v1.addTextChangedListener(watcher1);
v2.addTextChangedListener(watcher2);

For your convenience, the whole Activity class looks like this:

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

public class MainActivity extends ActionBarActivity {

    EditText v1, v2;
    private MyInputWatcher watcher1, watcher2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        v1 = (EditText)findViewById(R.id.editText1);
        v2 = (EditText)findViewById(R.id.editText2);

        watcher1 = new MyInputWatcher(v1);
        watcher2 = new MyInputWatcher(v2);

        v1.addTextChangedListener(watcher1);
        v2.addTextChangedListener(watcher2);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    class MyInputWatcher implements TextWatcher {
        private EditText et;

        private MyInputWatcher(EditText editText) {
            et = editText;
        }

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

        }

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

            switch (et.getId()) {
            case R.id.editText1: {
                v2.removeTextChangedListener(watcher2);
                v2.setText(s);// set whatever text you want to set in editText2
                v2.addTextChangedListener(watcher2);
                break;
            }
            case R.id.editText2: {
                v1.removeTextChangedListener(watcher1);
                v1.setText(s); // set whatever text you want to set in editText1
                v1.addTextChangedListener(watcher1);

                break;
            }
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    }
}

这篇关于Textwatcher给人错误#1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆