Android setText()给出了超出范围的索引

Android setText()给出了超出范围的索引,android,android-edittext,indexoutofboundsexception,Android,Android Edittext,Indexoutofboundsexception,我犯了一个错误,我似乎无法控制自己。我正在编写一个应用程序,允许用户将文本从EditText发送到TextView。如果用户出错,用户可以按空格键将从EditText发送的最新文本带到TextView。这有时有效,但有时会给我一个IndexOutOfBounds异常 textInput是一个EditText,back1,2,3是最近的三个字符串(back1是最近的) 上面的代码检查用户是否按了空格键,如果按了,该怎么办。如果用户在空的EditText上按空格键,则会收到最后发送的内容。如果他们再

我犯了一个错误,我似乎无法控制自己。我正在编写一个应用程序,允许用户将文本从
EditText
发送到
TextView
。如果用户出错,用户可以按空格键将从
EditText
发送的最新文本带到
TextView
。这有时有效,但有时会给我一个
IndexOutOfBounds
异常

textInput是一个EditText,back1,2,3是最近的三个字符串(back1是最近的)

上面的代码检查用户是否按了空格键,如果按了,该怎么办。如果用户在空的EditText上按空格键,则会收到最后发送的内容。如果他们再次进入太空,他们会得到下一个到最后一个发送的东西,依此类推。这仍然有点粗糙,但我希望你能理解

OutOfBounds异常来自于在
EditText
中选取一个较大的项目,点击空格,并将
EditText
设置为较小的字符串。我认为这是因为光标位于
EditText
的末尾,当文本变小时,光标就不在那里了,所以我尝试在
setText()前面添加
textInput.setSelection(0)
。那没用。我还尝试将
EditText
设置为
setText(“”
)。那也没用。如果我注释掉
setText(back#)
的行,一切正常

例如:

用户按顺序键入“你好”、“你好”和“你好”

back3=你好,back2=你好,back1=你好

按空格键一次将EditText设置为“hey”

第二次点击将崩溃,因为
设置范围(3…4)结束于长度2之外,可能是因为back 1大于back2。它应该将
编辑文本中的文本设置为“hi”

来自:

自:API级别1

调用此方法是为了通知您,在
s
中,从
start
开始的
count
字符刚刚替换了以前长度为
的旧文本尝试从此回调对
s
进行更改是错误的。

(我的重点。)

如果要对文本进行更多更改以响应现有更改,则应使用
posterextchanged
。即使在这种情况下,当您从
posterextchanged
更改文本时,也会重新调用处理程序,因此,请采取额外的预防措施以确保不会进入无限循环,例如:

public void afterTextChanged (Editable s) {
    static boolean is_reentrant = false;

    if (!is_reentrant) {
        is_reentrant = true;
        
        try {
            // do stuff
        } finally {
            is_reentrant = false;
        }
    }
}
我还没有测试过这段代码,但是类似的东西只会让你的代码在还没有运行的时候运行。在这种情况下,您不必担心线程安全,因为它只从同一线程内部调用。

来自:

自:API级别1

调用此方法是为了通知您,在
s
中,从
start
开始的
count
字符刚刚替换了以前长度为
的旧文本尝试从此回调对
s
进行更改是错误的。

(我的重点。)

如果要对文本进行更多更改以响应现有更改,则应使用
posterextchanged
。即使在这种情况下,当您从
posterextchanged
更改文本时,也会重新调用处理程序,因此,请采取额外的预防措施以确保不会进入无限循环,例如:

public void afterTextChanged (Editable s) {
    static boolean is_reentrant = false;

    if (!is_reentrant) {
        is_reentrant = true;
        
        try {
            // do stuff
        } finally {
            is_reentrant = false;
        }
    }
}

我还没有测试过这段代码,但是类似的东西只会让你的代码在还没有运行的时候运行。在这种情况下,您不必担心线程安全性,因为它只是从同一个线程内部调用的。

我没有读完整的问题,但应该读一行textInput.setSelection(textInput.getText().toString().length());不是textInput.setSelection(textInput.getText().toString().length()-1);?不,setSelection()在从“小->大”开始时按预期工作。此外,错误不止一次。我没有阅读整个问题,但应该是行textInput.setSelection(textInput.getText().toString().length());不是textInput.setSelection(textInput.getText().toString().length()-1);?不,setSelection()在从“小->大”开始时按预期工作。此外,错误不止一次。啊,我误解了s是什么。我想这是EditText中文本的新字符串副本。我不认为它是编辑文本中文本的实际对象。它是编辑文本中的实际文本对象吗?不管是哪种方式,将它移到后文本似乎是可行的。谢谢。我不知道它是实际的对象,还是在ContextChanged返回后进一步处理的副本,但是对
s
的更改反映在
EditText
的内容中。啊,我误解了s是什么。我想这是EditText中文本的新字符串副本。我不认为它是编辑文本中文本的实际对象。它是编辑文本中的实际文本对象吗?不管是哪种方式,将它移到后文本似乎是可行的。谢谢。我不知道它是实际的对象,还是在onTextChanged返回后进一步处理的副本,但是对
s
的更改反映在
EditText
的内容中。
public void afterTextChanged (Editable s) {
    static boolean is_reentrant = false;

    if (!is_reentrant) {
        is_reentrant = true;
        
        try {
            // do stuff
        } finally {
            is_reentrant = false;
        }
    }
}