EditText를 동적으로 생성한다면 TextWatcher를 하나 만들고 이걸 공유하면 될 것 같은데요. 이렇게 한번 해보시죠.
님의 코드에서 EditText등의 이름이 뭘 하는지 알 수가 없어서 코드를 읽는데 방해가 됩니다. 남들이 봐도 알기 쉬운 이름을 사용하세요. 이게 좋은 코드를 만드는데 첫번째로 강조되는 내용입니다.
먼저, TextWatcher에서 실제로 사용되는 메소드가 하나이므로 간단히 abstract class를 만듦니다. 이렇게 함으로써 MainActivity 에서 코드를 읽을 때 좀 더 집중하기가 쉬워집니다.
import android.text.TextWatcher;
public abstract class AfterTextChangedListener implements 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) {
}
}
EditText의 값을 검사하는 로직은 MainActivity에 있을 필요가 없고 반복되므로 반복을 줄이기 위한 클래스를 하나 만듭니다.
저의 예제는 심플한 구현이지 최선은 아닙니다.
public class EditField {
private String text;
private Integer value;
public String getText() {
return text;
}
public void setText(String text) {
try {
value = Integer.valueOf(text);
} catch (NumberFormatException e) {
value = null;
}
this.text = text;
}
public int getValue() {
return value;
}
public boolean validate() {
return value != null;
}
}
위의 클래스는 EditText 에 들어온 값 한개만 입력받아 검사하는 클래스이므로 3개의 입력의 받아서 검사하는 클래스를 만듭니다.
public class EditFieldsValidator {
private final EditField field1;
private final EditField field2;
private final EditField field3;
public EditFieldsValidator() {
field1 = new EditField();
field2 = new EditField();
field3 = new EditField();
}
public int getValue1() {
return this.field1.getValue();
}
public int getValue2() {
return this.field2.getValue();
}
public int getValue3() {
return this.field3.getValue();
}
public void setInput1(String text) {
this.field1.setText(text);
}
public void setInput2(String text) {
this.field2.setText(text);
}
public void setInput3(String text) {
this.field3.setText(text);
}
public void setInputs(String text1, String text2, String text3) {
setInput1(text1);
setInput2(text2);
setInput3(text3);
}
public boolean validate() {
return field1.validate() &&
field2.validate() &&
field3.validate();
}
}
마찬가지로 최대한 간편하게 코드를 만들었습니다.
다음은, Activity에 위의 클래스들을 적용한 코드입니다. 생각나는대로 만든 코드이므로 필요한 곳은 맞춰서 수정하시기 바랍니다.
그리고 계산을 하는 부분의 로직은 아직 좀 더 좋게 만들 수 있는 여지가 많습니다.
public class MainActivity extends AppCompatActivity {
private ViewGroup rootView;
private EditText EPMt1;
private EditText EPMt2;
private EditText EPMt3 = null;
private Button newEditBtn;
private TextView resultTxt;
private EditFieldsValidator editFieldsValidator;
private EditFieldsValidator validator() {
if (editFieldsValidator == null) {
editFieldsValidator =new EditFieldsValidator();
}
return editFieldsValidator;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
rootView = findViewById(R.id.rootView);
EPMt1 = findViewById(R.id.EPMt1);
EPMt2 = findViewById(R.id.EPMt2);
resultTxt = findViewById(R.id.resultTxt);
newEditBtn = findViewById(R.id.newEditBtn);
newEditBtn.setOnClickListener(v -> {
if (EPMt3 != null) return;
EPMt3 = createEditText();
EPMt3.addTextChangedListener(textChangedListener);
EPMt3.requestFocus();
});
}
@Override
protected void onDestroy() {
textChangedListener = null;
EPMt3 = null;
super.onDestroy();
}
private AfterTextChangedListener textChangedListener = new AfterTextChangedListener() {
@Override
public void afterTextChanged(Editable s) {
if (s == null) return;
calculate();
}
};
private void calculate() {
String input1 = EPMt1.getText().toString();
String input2 = EPMt2.getText().toString();
if (EPMt3 == null) {
// 필요한 처리 추가
return;
}
String input3 = EPMt3.getText().toString();
EditFieldsValidator validator = validator();
validator.setInputs(input1, input2, input3);
if (!validator.validate()) {
// 필요한 처리 추가
return;
}
int result = validator.getValue1() * validator.getValue2() + validator.getValu3();
resultTxt.setText("Result: " + result);
}
private EditText createEditText() {
EditText view = new EditText(this);
rootView.addView(view);
return view;
}
@Override
protected void onStart() {
super.onStart();
addTextChangedListeners();
}
private void addTextChangedListeners() {
EPMt1.addTextChangedListener(textChangedListener);
EPMt2.addTextChangedListener(textChangedListener);
if (EPMt3 != null) {
EPMt3.addTextChangedListener(textChangedListener);
}
}
@Override
protected void onStop() {
removeTextChangedListeners();
super.onStop();
}
private void removeTextChangedListeners() {
EPMt1.removeTextChangedListener(textChangedListener);
EPMt2.removeTextChangedListener(textChangedListener);
if (EPMt3 != null) {
EPMt3.removeTextChangedListener(textChangedListener);
}
}
}
담당하는 일이 다르다면 메소드나 클래스 등으로 분리를 하는 것이 좋습니다. 참고하셔서 님의 요구에 맞게 업그레이드 하시면 좋을 듯합니다.