2012-07-03 54 views
0

我有一个错误,我似乎无法包裹我的头。我正在编写一个应用程序,允许用户将文本从EditText发送到TextView。如果用户犯了错误,用户可以点击空格键将EditText发送的最新文本带到TextView。这有时会起作用,但有时候,它会给我一个例外。EditText.setText()给出索引越界

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

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

    if(count==1&&before==0&&s.toString().equals(" ")){ 
     textInput.setText(back1); 
    }else if(s.toString().equals(back1 + " ")){ 
     textInput.setText(back2); 
    }else if(s.toString().equals(back2 + " ")){ 
     textInput.setText(back3); //causes error if back2 > back3 
    } 

    textInput.setSelection(textInput.getText().toString().length()); 

上面的代码检查用户是否按下空格键,并且如果是这样,如何处理它。如果用户按空的EditText上的空间,他们会得到他们发送的最后一件事。如果他们再次击中空间,他们会获得他们发送的最后一件东西,等等。这仍然有点粗糙,但我希望你明白。

OutOfBounds例外来自于拍摄EditText中的大项目,击中空间并将EditText设置为更小的字符串。我认为这是因为光标位于EditText的末尾,当文本变小时不再存在,所以我尝试在setText()之前加上textInput.setSelection(0)。这没有帮助。我也尝试将EditText设置为setText("")。那也行不通。如果我注释掉setText(back#)的行,一切正常。

的例子:在“你好”,“嗨”和“嘿”

用户类型的顺序。

back3 = hello,back2 = hi,back1 = hey。

击中空间一旦将设置的EditText为“嘿”

第二抽头会崩溃,由于setSpan(3...4) ends beyond length 2,大概是因为背部1大于back2大。它应该设置在EditText为 “Hi”

+0

发布stacktrace。 – FoamyGuy

+1

我没有读完整个问题,但应该将textInput.setSelection(textInput.getText()。toString()。length());不是textInput.setSelection(textInput.getText()。toString()。length() - 1);? –

+0

不,从小到大的时候,setSelection()按预期工作。此外,错误不止一次。 –

回答

3

文本从the TextWatcher documentation

public abstract void onTextChanged (CharSequence s, int start, int before, int count) 

自:API等级1

这种方法被称为给你通知,内s ,从start开始的count字符刚刚替换了长度为before的旧文本。 尝试从此回调中更改s是错误的。

(我的重点。)

,如果你想改变文本更应对现有的变化,您应该使用afterTextChanged代替。即使在这种情况下,您的处理器将被调用重新entrantly当您更改从afterTextChanged文本,所以使用额外的预防措施,以确保你不会陷入无限循环,比如像这样:

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

    if (!is_reentrant) { 
     is_reentrant = true; 

     try { 
      // do stuff 
     } finally { 
      is_reentrant = false; 
     } 
    } 
} 

我没有测试过这个确切的代码片段,但类似的东西会让你的代码只运行,如果它还没有运行。在这种情况下,您不必担心线程安全问题,因为它只能从同一个线程中调用。

+0

啊,我误解了是什么。我在想这是EditText中文本的新字符串副本。我不认为它是EditText中文本的实际对象。它是编辑文本中的实际文本对象吗?无论哪种方式,将它移动到afterTextChanged似乎工作。谢谢。 –

+0

我不知道它是实际的对象,还是在onTextChanged返回后进一步处理的副本,但对's' *的更改反映在EditText的内容中。 –

+0

没有意识到这一点。谢谢。 –