2012-07-03 3 views
0

오류가 있습니다. 머리를 감쌀 수없는 것 같습니다. 나는 사용자가 EditText에서 TextView으로 텍스트를 보낼 수있는 앱을 작성 중이다. 사용자가 실수 한 경우 사용자는 스페이스 키를 눌러 EditText에서 보낸 가장 최근 텍스트를 TextView으로 가져올 수 있습니다. 때때로 작동하지만 다른 경우에는 IndexOutOfBounds 예외가 발생합니다.EditText.setText()는 인덱스가 경계를 벗어남을 나타냅니다.

에서 textInput는

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()); 

위의 코드 검사 사용자가 스페이스 키를 치면, 그래서 경우 (가장 최근 back1와) 최근 세 개의 문자열 back1,2,3 있습니다 글고입니다 그것으로 무엇을해야하는지. 사용자가 빈 EditText에서 스페이스를 누르면, 그들은 그들이 보낸 마지막 것을 얻습니다. 그들이 다시 우주 공간을 강타하면 그들이 보낸 마지막 물건을 얻습니다. 이것은 여전히 ​​조금 거칠지 만, 당신이 아이디어를 얻길 바랍니다.

OutOfBounds 예외는 EditText의 큰 항목을 가져 와서 공간을 뚫고 EditText을 작은 문자열로 설정하면 발생합니다. 커서가 EditText 끝에 있고 더 작아 졌을 때 더 이상있을 수 없다고 가정 했으므로 setText() 전에 textInput.setSelection(0)을 추가하려고했습니다. 그건 도움이되지 않았어. 또한 EditTextsetText("")으로 설정해 보았습니다. 그것도 작동하지 않았다. setText(back#)의 행을 주석 처리하면 모든 것이 잘 동작합니다.

예 : 순서로 "안녕하세요", "안녕하세요"와 "안녕하세요"에

사용자 유형.

back3 = hello, back2 = hi 및 back1 = hey.

타격 공간 되돌아가 1보다 큰 back2 아마도 때문에 setSpan(3...4) ends beyond length 2 때문에, "안녕"

번째 탭 충돌 할 것이다 글고를 설정한다. the TextWatcher documentation부터 EditText에 "안녕하세요"

+0

stacktrace를 게시하십시오. – FoamyGuy

+1

전체 질문을 읽지는 않았지만 textInput.setSelection (textInput.getText(). toString(). length()); textInput.setSelection (textInput.getText(). toString(). 길이() - 1); –

+0

아니요, small-> large에서 이동할 때 setSelection()이 예상대로 작동합니다. 게다가, 오류는 하나 이상입니다. –

답변

3

의 텍스트를 설정하도록되어 :

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

때문에

: 1

이 메서드를 호출 API 레벨이 s 내에서, 당신을 것을 통지 , count 문자는 start에서 시작하여 길이가 before 인 이전 텍스트로 바뀌 었습니다. 이 콜백에서 s을 변경하려고하면 오류가 발생합니다.

(내 강조.) 기존의 변화에 ​​대응하여 더 많은 텍스트를 변경하려는 경우 대신 afterTextChanged를 사용해야합니다

.

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

    if (!is_reentrant) { 
     is_reentrant = true; 

     try { 
      // do stuff 
     } finally { 
      is_reentrant = false; 
     } 
    } 
} 
: 당신이 afterTextChanged에서 텍스트를 변경, 그래서 당신은 이와 같은 같은 무한 루프받지 않습니다 확인하기 위해 여분의주의 사항을 사용하는 경우이 경우에도, 핸들러는 다시 entrantly 호출됩니다

이 정확한 스 니펫을 테스트하지는 않았지만 코드가 아직 실행되지 않은 경우에만 실행됩니다.이 스레드의 안전성에 대해서는 걱정할 필요가 없습니다.이 스레드는 동일한 스레드 내부에서만 호출되기 때문입니다.

+0

아, 나는 그게 뭔지 오해했습니다. 나는 그것이 EditText에있는 텍스트의 새로운 문자열 사본이라고 생각했다. 나는 그것이 EditText에서 텍스트의 실제 객체라고 생각하지 않았다. 편집 텍스트의 실제 텍스트 객체입니까? 어쨌든, 그것을 afterTextChanged로 옮기는 것은 효과가있는 것 같습니다. 감사. –

+0

그것이 실제 객체인지 또는 onTextChanged가 반환 된 후에 추가로 처리되는 사본인지는 모르지만's' *에 대한 변경 사항은 * EditText의 내용에 반영됩니다. –

+0

그 사실을 몰랐습니다. 감사. –

관련 문제