2012-07-03 77 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

沒有意識到這一點。謝謝。 –