Search code examples
javaandroidtextchanged

Multiple addTextChangedListeners without duplicating code


I currently have 24 EditText's on one of my screens which I need listeners for to update a total whenever one of them changes but I'm not sure how to set it up without having 24 separate pieces of code for listeners. The answer is probably really obvious but I can't quite figure it out, I found a few similar questions but couldn't get it to work myself.

Here is my code as it stands:

 private void loadPage() {
    round1Boxer1Input = (EditText) findViewById(R.id.round1Boxer1Input);
    totalBoxer1Text = (TextView) findViewById(R.id.totalBoxer1Text);
    round2Boxer1Input = (EditText) findViewById(R.id.round2Boxer1Input);
    round3Boxer1Input = (EditText) findViewById(R.id.round3Boxer1Input);
    round4Boxer1Input = (EditText) findViewById(R.id.round4Boxer1Input);
    round5Boxer1Input = (EditText) findViewById(R.id.round5Boxer1Input);
    round6Boxer1Input = (EditText) findViewById(R.id.round6Boxer1Input);
    round7Boxer1Input = (EditText) findViewById(R.id.round7Boxer1Input);
    round8Boxer1Input = (EditText) findViewById(R.id.round8Boxer1Input);
    round9Boxer1Input = (EditText) findViewById(R.id.round9Boxer1Input);
    round10Boxer1Input = (EditText) findViewById(R.id.round10Boxer1Input);
    round11Boxer1Input = (EditText) findViewById(R.id.round11Boxer1Input);
    round12Boxer1Input = (EditText) findViewById(R.id.round12Boxer1Input;)

    final EditText[] boxer1List = {round1Boxer1Input, round2Boxer1Input, round3Boxer1Input, round4Boxer1Input,
            round5Boxer1Input, round6Boxer1Input, round7Boxer1Input, round8Boxer1Input, round9Boxer1Input,
            round10Boxer1Input, round11Boxer1Input, round12Boxer1Input};

    round1Boxer1Input.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

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

        }

        @Override
        public void afterTextChanged(Editable editable) {
            totalBoxer1Text.setText(String.valueOf(addRoundsBoxer1(boxer1List)));
        }
    });
}

As it stands I think I'd have to make 24 of those listeners which I'm assuming isn't a great way of doing it.


Solution

  • For this specific case, why not have a method that takes an EditText and applies a TextWatcher to it? e.g.

    protected void applyTextWatcher(EditText roundInput, TextView boxerTotalText, EditText[] roundInputList){
        roundInput.addTextChangedListener(new TextWatcher() {
            ....
            @Override
            public void afterTextChanged(Editable editable) {
              boxerTotalText.setText(String.valueOf(sumRounds(roundInputList)));
            }
        });
    }
    

    Which you could use via:

    for(EditText roundInput : boxer1List)
        applyTextWatcher(roundInput, totalBoxer1Text, boxer1List);
    

    Although, you're still going to be duplicating a lot of code here, and it isn't very flexible (i.e. more/less rounds would mean deploying code changes), where you may want to take a more object-oriented approach. e.g.

    Instead of a list of EditTexts with no real reference, you could have a

    public class Round {
        int roundNumber;
    
        int boxer1Score;
        int boxer2Score;
    }
    
    public class RoundViewHolder {
        Round round;
    
        EditText boxer1Input;
        EditText boxer2Input;
    }
    

    Then, you'd have a List<RoundViewHolder> to work with instead of just the EditTexts, which links directly to the Round, which would help you with dynamically generated EditTexts based on how many rounds actually occurred.

    It's a bit of pseudo-code and not everything you need, but that should point you in the right direction.