0

次の入力のいずれかに基づいて、その人が受け取る給与を計算しようとしています-毎時、毎日、毎週、毎月、毎年。そのうちの 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
4

1 に答える 1

5

メイト !!私もここで立ち往生していました.... StackOverflowErrorが発生していました...しかし、おそらくTextWatcherを複数回インスタンス化したことが原因であると想定していました...しかし、実際には setText( ) 、これは TextWatcher のメソッドを無限に呼び出していました....だからここで私はそれをしました --- あなたのコードに従って --->

if(hourly!=null && hourly>0.0){
 if(etHourly.isFocused())   //this condition helped suppressing infinite loops
  etDaily.setText(String.valueOf(hourly*8));}
于 2012-10-17T18:30:04.047 に答える