M. Faraday M. Faraday - 16 days ago 5
Android Question

AddTextChangedListener to Loop-generated EditText views

I'm new to Android development. I'm facing a dead end developing an app for a project. Please take some time and help me out.

The problem:
I am generating some

EditText
views nested in a
LinearLayout
using a
for loop
.

For example:

LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {
EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
} // This code is for example purposes only.


Now, I can't seem to understand how I can set an addTextChangedListener on the EditText that is focused at a particular time and set that text on other EditTexts. Please tell me what approach should I adopt to achieve this. I tried my best to explain the problem; however, if there is still any ambiguity, feel free to comment and ask. I'm waiting for a solution to this problem.

In terms of screenshots:

What I have:

enter image description here

What I want:

enter image description here

I hope this clears things up!

**

EDIT:



Thanks to TylerSebastian for the solution. I got it to work. Here is the final code: (Inside OnCreate() method)

final LinearLayout rootView = (LinearLayout) findViewById(R.id.rootview);
for (int i=0,j=10;i<j;i++) {

final EditText et = new EditText(this);
rootView.addView(et);
et.setHint("EditText No. "+ i);
et.setId(i);
final TextWatcher textwatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

}

@Override
public void afterTextChanged(final Editable s) {
for (int i=0;i<10;i++){
EditText view = (EditText) findViewById(i);
if (view != et){
view.setText(s.toString());
}
}
}
};
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
et.addTextChangedListener(textwatcher);
} else {
et.removeTextChangedListener(textwatcher);
}
}
});

}


**

Answer

I don't have access to a machine with AS on it atm so no guarantee that the following is bug-free, but this should point you in the right direction:

final LinearLayout rootLayout = ...;

// within your loop
et.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void afterTextChanged(final Editable s) {
        for (int i = 0; i < rootLayout.getChildCount(); i++) {
            View view = rootLayout.getChildAt(i);

            if (view instanceof EditText && view != et) {
                ((EditText) view).setText(s.toString());
            }
        }
    }
});

edit: so the above will cause an infinite loop - see my comment below

How about:

final LinearLayout rootLayout = ...;

// again, within your loop
TextWatcher textWatcher = new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void afterTextChanged(final Editable s) {
        for (int i = 0; i < rootLayout.getChildCount(); i++) {
            View view = rootLayout.getChildAt(i);

            if (view instanceof EditText && view != et) {
                ((EditText) view).setText(s.toString());
            }
        }
    }
};

et.setOnFocusChangeListener(new OnFocusChangeListener() {
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
             ((EditText) view).addTextChangedListener(textWatcher);
        } else {
             ((EditText) view).removeTextChangedListener(textWatcher);
        }
    }
});

basically, only the focused element will have the textwatcher

Comments