11

検討:

TextView textView = new TextView(context);
    textView.addTextChangedListener(new TextWatcher() {

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

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {

            s.append("A");
        }
    });

にaを追加し、TextWatcherこれにTextView文字を追加したいTextView場合、ユーザーが文字を書き込むたびに、これはTextWatcherリスナーを呼び出し続けます。など、リスナーを再度StackOverFlow error呼び出さずにテキストを追加するにはどうすればよいですか?TextWatcher

4

5 に答える 5

32

それは簡単です:

@Override
public void afterTextChanged(Editable s) {
    editText.removeTextChangedListener(this);
    //Any modifications at this point will not be detected by TextWatcher,
    //so no more StackOverflowError 
    s.append("A");
    editText.addTextChangedListener(this);
}
于 2013-06-08T23:59:30.637 に答える
8

スタックオーバーフローを回避する別の方法:

TextView textView = new TextView(context);
    textView.addTextChangedListener(new TextWatcher() {

        boolean editing = false;

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

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (!editing){
               editing = true;
               s.append("A");
               editing = false;
        }

    }
});
于 2015-03-04T21:38:45.253 に答える
5

afterTextChangedのドキュメントには次のように書かれています。

このメソッドは、s内のどこかでテキストが変更されたことを通知するために呼び出されます。このコールバックからsにさらに変更を加えることは正当ですが、変更を加えるとこのメソッドが再帰的に再度呼び出されるため、無限ループにならないように注意してください。(他のafterTextChanged()メソッドがすでに他の変更を行ってオフセットを無効にしている可能性があるため、変更が行われた場所はわかりません。ただし、ここで知る必要がある場合は、でを使用setSpan(Object, int, int, int)onTextChanged(CharSequence, int, int, int)て場所をマークし、ここから検索できます。スパンが終わった。

だから、s.append("A")あなたたち一人一人と一緒call afterTextChanged()に。

于 2011-06-15T09:27:44.980 に答える
0

これを実行できるようにするためのいくつかの擬似コード:

フォーカスを変更するだけです...

だからこのように:

tv.isFocusable = false

tv.setText("my new text")

tv.isFocusable = true // Maybe post this to the message queue, so other jobs finish fist.


// Later on in your listener:

if(tv.isFocusable && tv.hasFocus())
    // Do something
else ignore
于 2021-06-08T08:58:32.300 に答える
-2

Kotlinバージョン

editText.addTextChangedListener(object: TextWatcher {
    override fun afterTextChanged(s: Editable?) {
        if (s.toString().isNotBlank()) {

            val formattedValue: String = // Do some formatting

            editText.removeTextChangedListener(this)
            editText.setText(formattedValue)
            editText.setSelection(editText.text.toString().length)
            editText.addTextChangedListener(this)
        }
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

    }

})
于 2017-11-01T07:39:28.333 に答える