私は2つの分野がある状況を持っています。 field1
とfield2
。 field2
が変更されたときに私がしたいのは空のfield1
だけです。そのため、最後には1つのフィールドにしかコンテンツがありません。
field1 = (EditText)findViewById(R.id.field1);
field2 = (EditText)findViewById(R.id.field2);
field1.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
field2.setText("");
}
});
field2.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
field1.setText("");
}
});
addTextChangedListener
をfield1
にのみ付けてもうまく動作しますが、両方のフィールドに対してそれを行うとアプリがクラッシュします。明らかに彼らは無期限にお互いを変えようとしているからです。 field1
が変更されると、現時点でfield2
をクリアします。field2
は変更されるのでfield1
をクリアします。
誰かが何か解決策を提案できますか?
あなたは、フィールドのテキストが空でないとき(つまり、長さが0と異なるとき)にのみクリアするためにチェックを追加することができます。
field1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0)
field2.setText("");
}
});
field2.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0)
field1.setText("");
}
});
TextWatcher
ここ のドキュメント。
私はこれが古いことを知っていますが、誰かがいつかまたこれに遭遇するかもしれません。
私はEditTextでsetTextを呼び出し、それが欲しくないときにonTextChangedが呼び出されるという同様の問題を抱えていました。私の最初の解決策は、リスナーによるダメージを元に戻すためにsetText()を呼び出した後にコードを書くことでした。しかし、それはそれほどエレガントではありませんでした。いくつかの調査とテストを行った後、getText()。clear()を使用するとsetText( "")とほぼ同じ方法でテキストがクリアされることがわかりました。私の問題を解決しました。私はすべてのsetText( "")呼び出しをgetText()。clear()に切り替えましたが、もう包帯は必要ありませんでした。それであなたの問題も解決するでしょう。
これを試して:
Field1 = (EditText)findViewById(R.id.field1);
Field2 = (EditText)findViewById(R.id.field2);
Field1.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
Field2.getText().clear();
}
});
Field2.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
Field1.getText().clear();
}
});
Androidの開発にKotlinを使用している場合は、次のコードを使用してTextChangedListener()
を追加できます。
myTextField.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
少し遅れた回答ですが、再利用可能な解決策があります。
/**
* An extension of TextWatcher which stops further callbacks being called as
* a result of a change happening within the callbacks themselves.
*/
public abstract class EditableTextWatcher implements TextWatcher {
private boolean editing;
@Override
public final void beforeTextChanged(CharSequence s, int start,
int count, int after) {
if (editing)
return;
editing = true;
try {
beforeTextChange(s, start, count, after);
} finally {
editing = false;
}
}
protected abstract void beforeTextChange(CharSequence s, int start,
int count, int after);
@Override
public final void onTextChanged(CharSequence s, int start,
int before, int count) {
if (editing)
return;
editing = true;
try {
onTextChange(s, start, before, count);
} finally {
editing = false;
}
}
protected abstract void onTextChange(CharSequence s, int start,
int before, int count);
@Override
public final void afterTextChanged(Editable s) {
if (editing)
return;
editing = true;
try {
afterTextChange(s);
} finally {
editing = false;
}
}
public boolean isEditing() {
return editing;
}
protected abstract void afterTextChange(Editable s);
}
そのため、上記を使用した場合、TextWatcher内でsetText()
呼び出しが発生しても、TextWatcherが再度呼び出されることはありません。
/**
* A setText() call in any of the callbacks below will not result in TextWatcher being
* called again.
*/
public class MyTextWatcher extends EditableTextWatcher {
@Override
protected void beforeTextChange(CharSequence s, int start, int count, int after) {
}
@Override
protected void onTextChange(CharSequence s, int start, int before, int count) {
}
@Override
protected void afterTextChange(Editable s) {
}
}
私はまた同じ問題に直面し、スタックフル例外を取得し続けており、私は以下の解決策を考え出しています。
edt_amnt_sent.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (skipOnChange)
return;
skipOnChange = true;
try {
//method
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
skipOnChange = false;
}
}
});
edt_amnt_receive.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (skipOnChange)
return;
skipOnChange = true;
try
{
//method
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
skipOnChange = false;
}
}
});
最初に宣言されたブール値skipOnChange = false;
別のEditText
を空に設定する前に、Stringを確認してください。 Field1
が空の場合、なぜ再度( "")に変更する必要がありますか?だからあなたは s.lenght()であなたの文字列のサイズをチェックすることができます または他の解決策
あなたは文字列の長さをチェックすることができるもう一つの方法は次のとおりです。
String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}
HasFocus()メソッドを使うこともできます。
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (Field2.hasfocus()){
Field1.setText("");
}
}
ユーザーが入力したとおりに温度スケールを変換するために取り組んでいた大学の課題についてこれをテストしました。