【问题标题】:TextWatcher afterTextChanged causes stackoverflow in androidTextWatcher afterTextChanged导致android中的stackoverflow
【发布时间】:2012-01-27 13:03:57
【问题描述】:

我有一个方法drawItems(),它每次都会创建一个新布局并将其设置为contentView。而且我还有一个控件EditText,它应该在其内容发生更改时删除其他元素。

edit.addTextChangedListener(new TextWatcher() {

                    public void afterTextChanged(Editable s) {
                        currentText = s.toString();
                        drawItems();
                    }

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

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

我想要做的是保存它的当前文本,删除所有元素并只留下这个EditTextsaved string。当我尝试运行此应用程序时,引发的错误是 StackOverflow,因为它无限次呈现 drawItems 方法。为什么即使我不更改其内容,它也会在afterTextChanged 中呈现drawItems?它甚至在整个页面加载之前就被渲染了。

【问题讨论】:

  • 只是一个疯狂的猜测,但我认为你可能会从afterTextChanged 触发onTextChanged,这显然会无限循环。我会在这两种方法中都设置一个断点并验证是(或不是)这种情况

标签: android layout stack-overflow


【解决方案1】:

这个小 sn-p 可能会有所帮助:

editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start,
                    int before, int count) {
            }

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

            @Override
            public void afterTextChanged(Editable s) {

                idAnswerEditText.removeTextChangedListener(this);

                String someString = StringUtil.doSomething(s.toString());
                idAnswerEditText.getText().clear();
                idAnswerEditText.getText().append(someString);
                idAnswerEditText.setSelection(someString.length());

                idAnswerEditText.addTextChangedListener(this);

            }

});

当您在用户键入时编辑字符串时,请移除侦听器并对文本执行您需要执行的任何操作,然后将侦听器重新附加到 EditText。

【讨论】:

  • 那里!感谢您的建议。
【解决方案2】:

调用此方法是为了通知您,在 s 中的某处,文本已更改。 在此回调中对 s 进行进一步更改是合法的,但请注意不要让自己陷入无限循环,因为您所做的任何更改都会导致再次递归调用此方法。(您是未告知更改发生的位置,因为其他 afterTextChanged() 方法可能已经进行了其他更改并使偏移量无效。但是如果您需要在这里了解,可以在 onTextChanged(CharSequence, int, int, int) 来标记您的位置,然后从此处查找 span 结束的位置。

放:

public void afterTextChanged(Editable s) {
    if (MyEditText.getText().toString().compareTo(s.toString()) != 0)
    {
        // your code ...
    }
}

【讨论】:

    【解决方案3】:

    正如@DroidIn.net 在评论中所说,您可能在 afterTextChanged 处理中触发了文本更改事件 - 可能在 drawItems() 中。

    您可以通过使用 Handler 来推迟处理 drawItems 来解决堆栈溢出异常,但这可能只会让您陷入无限循环。您应该查看 drawItems,并确保它们不会更改您的编辑文本,从而导致更改再次更改编辑文本等等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      相关资源
      最近更新 更多