次の入力のいずれかに基づいて、その人が受け取る給与を計算しようとしています-毎時、毎日、毎週、毎月、毎年。そのうちの 1 つが入力されると、残りは自動的に再計算されます。
手順は次のとおりです。
まず、Double
アクティビティの上部に定義された 5 つの型変数があります。時間ごと、日ごと、週ごと、月ごと、年ごとです。次に、これらの変数に対応する 5 つの EditText フィールドがあります。TextWatcher
これら 5 つの EditTextを実装するカスタム サブクラスをアタッチしました。
例えば:
etHourly = (EditText) findViewById(R.id.etHourly);
etHourly.addTextChangedListener(new EditTextWatcher(etHourly));
このカスタム クラスには、渡されたビューを受け入れて格納するコンストラクターがあります。これは、TextWatcher
クラスの既定のメソッドが、変更を呼び出したビューを見つける方法を提供しないためです。
渡されたビューをカスタム サブクラス内のローカル変数として保存した後、このサブクラス内の実装に進みafterTextChanged
、渡された EditText の値を取得しDouble
、アクティビティの上部にある対応する定義済み変数に として保存します。(たとえば、渡された EditText が週給の場合、この EditText の値を double としてweekly
変数に設定します。
最後に、メソッドの終了直前にafterTextChanged
別のカスタム メソッドを呼び出します。このメソッドにRecalculate()
は、if()
時間単位、日単位、週単位、月単位、または年単位が設定されているかどうかを確認する一連の があり、設定されている場合はsetText()
残りの EditText を計算して使用します。問題はsetText()
、これらの EditText ごとに TextWatchers が呼び出され、無限ループが発生することです。
どうすればこれを克服できますか?
これをよりよく理解するためのコードを次に示します。onCreate の前:
Double hourly, daily, weekly, monthly, yearly = 0.0;
EditText etHourly, etDaily, etWeekly, etMonthly, etYearly;
onCreate() の内部:
etHourly = (EditText) findViewById(R.id.etHourly);
etDaily = (EditText) findViewById(R.id.etDaily);
etWeekly = (EditText) findViewById(R.id.etWeekly);
etMonthly = (EditText) findViewById(R.id.etMonthly);
etYearly = (EditText) findViewById(R.id.etYearly);
etHourly.addTextChangedListener(new EditTextWatcher(etHourly));
etDaily.addTextChangedListener(new EditTextWatcher(etDaily));
etWeekly.addTextChangedListener(new EditTextWatcher(etWeekly));
etMonthly.addTextChangedListener(new EditTextWatcher(etMonthly));
etYearly.addTextChangedListener(new EditTextWatcher(etYearly));
EditTextWatcher
サブクラス:
private class EditTextWatcher implements TextWatcher {
EditText v;
public EditTextWatcher(EditText view) {
this.v = view;
}
public void afterTextChanged(Editable s) {
Reinit();
// Only if the currently edited text field contains something
if (v.getText().toString().length() > 0) {
switch (v.getId()) {
case R.id.etHourly:
hourly = getTvAsDouble(etHourly);
break;
case R.id.etDaily:
daily = getTvAsDouble(etDaily);
break;
case R.id.etWeekly:
weekly = getTvAsDouble(etWeekly);
break;
case R.id.etMonthly:
monthly = getTvAsDouble(etMonthly);
break;
case R.id.etYearly:
yearly = getTvAsDouble(etYearly);
break;
default:
}
}
Recalculate();
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
}
再初期化():
hourly = daily = weekly = monthly = yearly = 0.0;
再計算():
if(hourly!=null && hourly>0.0){
etDaily.setText(String.valueOf(hourly*8));
}
// I will complete the other if's once this works