web-dev-qa-db-ja.com

EditTextのコンテンツがユーザーまたはプログラムによって変更されたかどうかを検出しますか?

ユーザーが何かを入力することによって、またはプログラムがテキストを変更するアプリによってEditTextが変更されたかどうかを検出する方法が必要です。これを行う標準的な方法はありますか? setText()の前にTextWatcherの設定を解除し、その後再び設定を戻すなど、常にハッキングを行うことができると思いますが、これを行うにはもっと良い方法が必要です...

EditTextがTextWatcherでフォーカスされているかどうかを確認しようとしましたが、スクロールするとEditTextが「半ランダム」にフォーカスされるため、ほとんど役に立ちませんでした...

背景

すべてのリストアイテムにEditTextsを含むリストビューがあります。ユーザーがスクロールしたときに再利用できるように、EditTextの値を保存するという基本的な問題を整理しました。

また、すべてのEditTextの値を合計し、ユーザーがいずれかのEditTextのコンテンツを編集したときに合計を表示するTextWatcherもあります。

問題は、リストをスクロールしているときに、カスタムアダプターがbindView()のEditTextsに保存された値を再入力すると、TextWatchers afterTextChanged()メソッドもトリガーされ、スクロールが発生することです。加算機能がトリガーされるため、遅れます。

47
Magnus W

これはかなり前に整理されましたが、ここで答えを探している人のために、私がやったことは次のとおりです:

プログラムで変更する直前に、EditTextのTagを任意の値に設定し、値を変更してから、Tagをnullにリセットしました。次に、TextWatcher.afterTextChanged()メソッドで、Tagがnullかどうかを確認して、値が変更されたのがユーザーかプログラムかを判断します。魔法のように機能します!

このようなもの:

edit.setTag( "arbitrary value" );
edit.setText( "My Text Value" );
edit.setTag(null);

その後

public void afterTextChanged(Editable s) {
    if( view.getTag() == null )             
        // Value changed by user
    else
        // Value changed by program
}
48
Magnus W

受け入れられた答えは完全に有効ですが、別のアプローチがあります。

@Override
public void onTextChanged(CharSequence charSequence, 
                         int start, int before, int count) {
    boolean userChange = Math.abs(count - before) == 1; 
    if (userChange) { 

    }
}

変更が単一の文字であるかどうかを確認することで機能します。これは、コピーと貼り付けの操作が見落とされる可能性があり、単一の文字のユーザー以外の変更も見逃される可能性があるため、絶対確実なソリューションではありません。ユースケースによっては、これが実行可能なソリューションになる場合があります。

7
Petrus

私に役立ったのは、ブール型のcanListenInputフィールドを持つことです。ウォッチャー内で使用します。

    email.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
            if (canListenInput) {
                emailChanged = true;
            }
        }
    });

プログラムでテキストを変更する前にクリアしてください。 onAttachedToWindow内に設定し、(状態の後)復元します。

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    canListenInput = true;
}
1
konmik