0

頭を包み込むことができないエラーが発生しています。ユーザーが から にテキストを送信できるようにするアプリを作成していEditTextますTextViewEditTextユーザーが間違えた場合、ユーザーはスペース キーを押して、から送信された最新のテキストを に移動できTextViewます。これはうまくいくこともありますが、IndexOutOfBounds例外が発生することもあります。

textInput は EditText、back1、2、3 は最新の 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 でスペースを押すと、最後に送信したものを取得します。もう一度スペースにヒットすると、最後から 2 番目に送信したものが取得されます。これはまだ少し大雑把ですが、アイデアを理解していただければ幸いです。

OutOfBounds 例外は、 で大きな項目を取得し、EditTextスペースをヒットEditTextし、 をより小さな文字列に設定することから発生します。カーソルが の最後にありEditText、テキストが小さくなったときにカーソルがそこになくなるためだと思ったので、textInput.setSelection(0)の直前に追加してみましたsetText()。それは役に立ちませんでした。を に設定してみEditTextましたsetText("")。それもうまくいきませんでした。の行をコメントアウトするとsetText(back#)、すべて正常に動作します。

例:

ユーザーは、「こんにちは」、「こんにちは」、「やあ」の順に入力します。

back3 = こんにちは、back2 = こんにちは、back1 = こんにちは。

スペースを 1 回押すと、EditText が「hey」に設定されます

setSpan(3...4) ends beyond length 2おそらく背面 1 が背面 2 よりも大きいため、2 回目のタップはクラッシュします。のテキストEditTextを「こんにちは」に設定することになっています

4

1 に答える 1

3

ドキュメントから:_TextWatcher

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

以来: API レベル 1

このメソッドは、 内sで、 でcount始まる文字startが長さ の古いテキストに置き換わったことを通知するために呼び出されますbeforeこのコールバックから変更しようとするとエラーになります。s

(私の強調。)

afterTextChanged既存の変更に応じてテキストをさらに変更したい場合は、代わりに使用する必要があります。この場合でも、テキストを から変更するとハンドラーが再入可能に呼び出されるafterTextChangedため、次のような無限ループに陥らないように特別な予防措置を講じてください。

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

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

この正確なスニペットをテストしていませんが、そのようなものは、コードがまだ実行されていない場合にのみ実行されます。この場合、同じスレッド内からのみ呼び出されるため、スレッドセーフについて心配する必要はありません。

于 2012-07-03T22:16:54.080 に答える