ユーザーが何かを入力することによって、またはプログラムがテキストを変更するアプリによってEditTextが変更されたかどうかを検出する方法が必要です。これを行う標準的な方法はありますか? setText()
の前にTextWatcherの設定を解除し、その後再び設定を戻すなど、常にハッキングを行うことができると思いますが、これを行うにはもっと良い方法が必要です...
EditTextがTextWatcherでフォーカスされているかどうかを確認しようとしましたが、スクロールするとEditTextが「半ランダム」にフォーカスされるため、ほとんど役に立ちませんでした...
背景
すべてのリストアイテムにEditTextsを含むリストビューがあります。ユーザーがスクロールしたときに再利用できるように、EditTextの値を保存するという基本的な問題を整理しました。
また、すべてのEditTextの値を合計し、ユーザーがいずれかのEditTextのコンテンツを編集したときに合計を表示するTextWatcherもあります。
問題は、リストをスクロールしているときに、カスタムアダプターがbindView()
のEditTextsに保存された値を再入力すると、TextWatchers afterTextChanged()
メソッドもトリガーされ、スクロールが発生することです。加算機能がトリガーされるため、遅れます。
これはかなり前に整理されましたが、ここで答えを探している人のために、私がやったことは次のとおりです:
プログラムで変更する直前に、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
}
受け入れられた答えは完全に有効ですが、別のアプローチがあります。
@Override
public void onTextChanged(CharSequence charSequence,
int start, int before, int count) {
boolean userChange = Math.abs(count - before) == 1;
if (userChange) {
}
}
変更が単一の文字であるかどうかを確認することで機能します。これは、コピーと貼り付けの操作が見落とされる可能性があり、単一の文字のユーザー以外の変更も見逃される可能性があるため、絶対確実なソリューションではありません。ユースケースによっては、これが実行可能なソリューションになる場合があります。
私に役立ったのは、ブール型のcanListenInputフィールドを持つことです。ウォッチャー内で使用します。
email.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (canListenInput) {
emailChanged = true;
}
}
});
プログラムでテキストを変更する前にクリアしてください。 onAttachedToWindow内に設定し、(状態の後)復元します。
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
canListenInput = true;
}