Могу ли я использовать один и тот же TextWatcher на разных виджетах EditText

У меня есть форма. Я хочу отобразить вычисление в "реальном времени", когда пользователь вводит различные значения в некоторые поля int. Я заставил свой Activity реализовать интерфейс TextWatcher и установить слушателя на 3 различных поля EditText, но, похоже, Textwatcher обнаруживает только первый EditText, объявленный в коде Activity.

Вы можете видеть из кода ниже, я пытаюсь захватить несколько полей, преобразовать их в целые и отобразить вывод в поле EditText в нижней части формы. Куда я иду не так? Нужно ли реализовывать textWatcher индивидуально для всех полей EditText? Это было бы довольно многословное решение, делающее мой код намного длиннее, чем хотелось бы

public class NewStageFormActivity extends AppCompatActivity implements TextWatcher{

    Context mContext;

    EditText mStageName, mPaperTargets, mHitsPerTarget, mSteelTargets, mSteelNPMs, mOutput;
    Spinner mScoringType, mStrings;
    CheckBox mNoShoots, mNPMs;
    Button mSaveButton;
    Match mGlobalMatch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stage_form);

        mContext = this;
        mGlobalMatch = GlobalMatch.getMatch();

        mStageName = (EditText)findViewById(R.id.stage_name_et);
        mPaperTargets = (EditText)findViewById(R.id.paper_targets_et);
        mHitsPerTarget = (EditText)findViewById(R.id.hits_per_target_et);
        mSteelTargets = (EditText)findViewById(R.id.steel_targets_et);
        mSteelNPMs = (EditText)findViewById(R.id.steel_npm_et);
        mScoringType = (Spinner)findViewById(R.id.scoring_type_spinner);
        mStrings = (Spinner)findViewById(R.id.strings_spinner);
        mNoShoots = (CheckBox)findViewById(R.id.no_shoots_cb);
        mNPMs = (CheckBox)findViewById(R.id.npm_cb);
        mSaveButton = (Button)findViewById(R.id.save_button);
        mOutput = (EditText)findViewById(R.id.output_et);

        // paper * hitsPer + steel
        mPaperTargets.addTextChangedListener(this);
        mSteelTargets.addTextChangedListener(this);
        mSteelTargets.addTextChangedListener(this);

        mSaveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mStageName.getText().toString().equals("") || mPaperTargets.getText().toString().equals("") ||
                        mHitsPerTarget.getText().toString().equals("") || mSteelTargets.getText().toString().equals("") ||
                        mSteelNPMs.getText().toString().equals("")){
                    Toast.makeText(mContext, "You must fill in all form fields", Toast.LENGTH_SHORT).show();
                } else {
                    String name = mStageName.getText().toString();
                    String type = mScoringType.getSelectedItem().toString();
                    int strings = Integer.valueOf(mStrings.getSelectedItem().toString());
                    int paperTargets = Integer.valueOf(mPaperTargets.getText().toString());
                    int hitsPerTarget = Integer.valueOf(mHitsPerTarget.getText().toString());
                    boolean noShoots;
                    boolean npms;
                    if(mNoShoots.isChecked()){
                        noShoots = true;
                    } else {
                        noShoots = false;
                    }
                    if(mNPMs.isChecked()){
                        npms = true;
                    } else {
                        npms = false;
                    }
                    int steelTargets = Integer.valueOf(mSteelTargets.getText().toString());
                    int steelNPMs = Integer.valueOf(mSteelNPMs.getText().toString());

                    MatchStage matchStage = new MatchStage(name, type, strings, paperTargets, hitsPerTarget,
                            noShoots, npms, steelTargets, steelNPMs);

                    mGlobalMatch.getStages().add(matchStage);

                    String jsonString = new Gson().toJson(mGlobalMatch);
                    MatchHelper.updateFile(mContext, MatchHelper.createFileName(mGlobalMatch.getMatchId()),
                            jsonString);

                    Intent intent = new Intent(mContext, StagesListActivity.class);
                    startActivity(intent);
                }
            }
        });


    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {


        int paper = Integer.valueOf(mPaperTargets.getText().toString());
        int hitsPer = Integer.valueOf(mHitsPerTarget.getText().toString());
        int steel = Integer.valueOf(mSteelTargets.getText().toString());

        int minRound = (paper * hitsPer) + steel;
        int points = minRound * 5;

        mOutput.setText("Minimum rounds: " + (minRound) + "\t\t Points: " + points);
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }
}

1 ответ

Решение

По моему опыту у меня были проблемы с использованием того же TextWatcher на нескольких EditText, Вы можете обойти это, создав метод, который создает новый экземпляр TextWatcher для каждого EditText так что ваш код не весь многословен. Попробуйте что-то вроде этого:

Избавляться от implements TextWatcher для тебя Activity и это связанные методы. Реализуйте метод createTextWatcher():

private TextWatcher createTextWatcher() {
    return new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            // Copy your original code
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            // Copy your original code
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // Copy your original code
        }
    };   
}

Теперь, чтобы использовать это так:

mPaperTargets.addTextChangedListener(createTextWatcher());
mSteelTargets.addTextChangedListener(createTextWatcher());

Ответ с наибольшим количеством голосов по ссылке @Natan Felipe также демонстрирует использование одного экземпляра TextWatcher в EditText,

Другие вопросы по тегам