Câu trả lời:
Tôi chỉ gặp phải vấn đề này. Tôi đã giải quyết nó bằng cách tạo ra một triển khai lớp bên trong, trong TextWatcher
đó lấy View làm đối số. Sau đó, trong quá trình thực hiện phương thức, chỉ cần bật chế độ xem để xem cái nào Editable
đến từ
Tờ khai:
private class GenericTextWatcher implements TextWatcher{
private View view;
private GenericTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
String text = editable.toString();
switch(view.getId()){
case R.id.name:
model.setName(text);
break;
case R.id.email:
model.setEmail(text);
break;
case R.id.phone:
model.setPhone(text);
break;
}
}
}
Sử dụng:
name = (EditText) findViewById(R.id.name);
name.setText(model.getName());
name.addTextChangedListener(new GenericTextWatcher(name));
email = (EditText) findViewById(R.id.email);
email.setText(model.getEmail());
email.addTextChangedListener(new GenericTextWatcher(email));
phone = (EditText) findViewById(R.id.phone);
phone.setText(model.getPhone());
phone.addTextChangedListener(new GenericTextWatcher(phone));
Single TextWatcher for multiple EditTexts
. Đây là 3 trường hợp của một lớp TextWatcher. Vì vậy, 3 TextWatchers riêng biệt đang kiểm soát 3 EditTexts.
Nếu bạn muốn chỉ sử dụng afterTextChanged so sánh các chỉnh sửa:
@Override
public void afterTextChanged(Editable editable) {
if (editable == mEditText1.getEditableText()) {
// DO STH
} else if (editable == mEditText2.getEditableText()) {
// DO STH
}
}
==
thay vì .equals()
.
public class MultiTextWatcher {
private TextWatcherWithInstance callback;
public MultiTextWatcher setCallback(TextWatcherWithInstance callback) {
this.callback = callback;
return this;
}
public MultiTextWatcher registerEditText(final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
callback.beforeTextChanged(editText, s, start, count, after);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
callback.onTextChanged(editText, s, start, before, count);
}
@Override
public void afterTextChanged(Editable editable) {
callback.afterTextChanged(editText, editable);
}
});
return this;
}
interface TextWatcherWithInstance {
void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after);
void onTextChanged(EditText editText, CharSequence s, int start, int before, int count);
void afterTextChanged(EditText editText, Editable editable);
}
}
new MultiTextWatcher()
.registerEditText(editText1)
.registerEditText(editText2)
.registerEditText(editText3)
.setCallback(new TextWatcherWithInstance() {
@Override
public void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after) {
// TODO: Do some thing with editText
}
@Override
public void onTextChanged(EditText editText, CharSequence s, int start, int before, int count) {
// TODO: Do some thing with editText
}
@Override
public void afterTextChanged(EditText editText, Editable editable) {
// TODO: Do some thing with editText
}
});
TextView
sự thay đổi đến từ đâu.
Nếu bạn muốn sử dụng so sánh onTextChangedhashCode()
được đề cập dưới đây -
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(charSequence.hashCode() == first_edit_text.getText().hashCode()){
// do other things
}
if(charSequence.hashCode() == second_edit_text.getText().hashCode()){
// do other things
}
}
Hoặc là
Nếu bạn muốn sử dụng afterTextChanged so sánh Editable
được đề cập dưới đây -
@Override
public void afterTextChanged(Editable editable) {
if (editable == first_edit_text.getEditableText()) {
// do other things
} else if (editable == second_edit_text.getEditableText()) {
// do other things
}
}
Nó sẽ hoạt động với mã này
TextWatcher watcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//YOUR CODE
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//YOUR CODE
}
@Override
public void afterTextChanged(Editable s) {
String outputedText = s.toString();
mOutputText.setText(outputedText);
}
};
Sau đó thêm điều này vào oncreate
mInputText.addTextChangedListener(watcher);
e2.addTextChangedListener(watcher);
e3.addTextChangedListener(watcher);
e4.addTextChangedListener(watcher);
Tôi biết đây là một vấn đề cũ, và có quyết định đúng đắn. Tôi sẽ viết riêng của họ, có thể nó sẽ giúp được ai đó.
Mô phỏng ví dụ cổ điển nơi chúng tôi có N EditText và chúng tôi muốn hiển thị nút nếu tất cả các trường được điền. Ví dụ này có ý nghĩa, đặc biệt nếu tiếp tục sử dụng trình xác nhận cho mỗi người.
Tôi đã làm một ví dụ liên quan đến vấn đề này, nhưng bạn có thể thực hiện bất kỳ bộ nào
MultiEditText. Class
public class MultiEditText extends AppCompatActivity{
EditText ed_1, ed_2, ed_3;
Button btn_ok;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multi_edit_text);
ed_1 = (EditText) findViewById(R.id.ed_1);
ed_2 = (EditText) findViewById(R.id.ed_2);
ed_3 = (EditText) findViewById(R.id.ed_3);
btn_ok = (Button) findViewById(R.id.btn_ok);
btn_ok.setEnabled(false);
//if want more here can cycle interface List
EditText[] edList = {ed_1, ed_2, ed_3};
CustomTextWatcher textWatcher = new CustomTextWatcher(edList, btn_ok);
for (EditText editText : edList) editText.addTextChangedListener(textWatcher);
}
}
Trông nó rất đơn giản.
public class CustomTextWatcher implements TextWatcher {
View v;
EditText[] edList;
public CustomTextWatcher(EditText[] edList, Button v) {
this.v = v;
this.edList = edList;
}
@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(Editable s) {
for (EditText editText : edList) {
if (editText.getText().toString().trim().length() <= 0) {
v.setEnabled(false);
break;
}
else v.setEnabled(true);
}
}
}
Tôi sẽ thêm một bố cục, vì vậy bạn không lãng phí thời gian
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:id="@+id/ed_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp" />
<EditText
android:id="@+id/ed_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/ed_1"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp" />
<EditText
android:id="@+id/ed_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/ed_2"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp" />
<Button
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ed_3"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:text="OK" />
</RelativeLayout>
Yêu cầu lớp của bạn kế thừa từ Activity và triển khai TextWatcher.
Sau đó thông qua sự kỳ diệu của đa hình, bạn chỉ cần đăng ký vào các sự kiện.
Điều này sẽ không cho bạn biết TextEdit đã thay đổi gì, tuy nhiên bằng cách sử dụng kết hợp câu trả lời này và câu trả lời của Sky Kelsey , bạn có thể sắp xếp nó một cách độc đáo.
public YourActivity extends Activity implements TextWatcher {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_YourActivity);
//Subscribe to the events
EditText txt1 = (EditText) findViewById(R.id.txt1);
txt1.addTextChangedListener(this);
EditText txt2 = (EditText) findViewById(R.id.txt2);
txt2.addTextChangedListener(this);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
EditText txt1 = (EditText) findViewById(R.id.txt1);
EditText txt2 = (EditText) findViewById(R.id.txt2);
// You probably only want the text value from the EditText. But you get the idea.
doStuff(txt1,txt2);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.calc, menu);
return true;
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
}
TextWatcher watcher = 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) {
}
};
Sau đó:
editText1.addTextChangedListener(watcher);
editText2.addTextChangedListener(watcher);
editText3.addTextChangedListener(watcher);
public class MainActivity extends AppCompatActivity{
EditText value1, value2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//instantiate EditText controls
value1 = (EditText)findViewById(R.id.txtValue1);
value2 = (EditText)findViewById(R.id.txtValue2);
//set up text changed listener
value1.addTextChangedListener(new TextChange(value1));
value2.addTextChangedListener(new TextChange(value2));
//inner class
private class TextChange implements TextWatcher {
View view;
private TextChange (View v) {
view = v;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
switch (view.getId()) {
case R.id.txtValue1:
//insert your TextChangedListener codes here
break;
case R.id.txtValue2:
//insert your TextChangedListener codes here
break;
}
}
}
}
}
Đây là giải pháp của tôi cho kotlin. Bạn chỉ có thể sử dụng đẳng thức tham chiếu (===) để kiểm tra cùng một đối tượng và nó hoạt động hoàn hảo.
val mTextWatcher = object : TextWatcher {
override fun afterTextChanged(et: Editable?) {
when {
et === et1.editableText -> {
Toast.makeText(this@MainActivity, "EditText 1", Toast.LENGTH_LONG).show()
}
et === et2.editableText -> {
Toast.makeText(this@MainActivity, "EditText 2", Toast.LENGTH_LONG).show()
}
}
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
}
et1.addTextChangedListener(mTextWatcher)
et2.addTextChangedListener(mTextWatcher)
Tôi biết câu hỏi này đã cũ, tuy nhiên tôi muốn chia sẻ một trong những giải pháp của mình (trong Kotlin). Giải pháp của tôi là cải thiện câu trả lời của @Shwarz Andrei, lý do của tôi là nếu bạn muốn thao túng nhiều thứ / đối tượng hơn.
Thay vì vượt qua cả hai list of EditTexts
và a Button
làm thông số, bạn chỉ vượt qua list of editText
. Sau đó, trong lớp tùy chỉnh của bạn, bạn sẽ triển khai lambda như sau:
var hasFilled:((Boolean)->Unit)? = null
Sau đó, bạn sẽ thiết lập hoặc nâng nó bên trong afterTextChanged
override fun afterTextChanged(p0: Editable?) {
for (edit in _editTextList) {
if (edit?.text.toString().trim().isEmpty()) {
hasFilled?.invoke(false) //<-- here
break
} else {
hasFilled?.invoke(true) //<--- here
}
}
}
Vì vậy, mỗi lần, có một sự thay đổi trong một số Chỉnh sửa, lambda của bạn được gọi
val editTexts = listOf(emailEditText,passwordEditText) // your list of editText
val textWatcher = customTextWatcher(editTexts) // initialize your custom object
editTexts.forEach { it -> it?.addTextChangedListener(textWatcher) } // each editText would listen for changes
textWatcher.hasFilled = { value -> // now you have access to your lambda
if (value != true) {
// change the state of the button to unable
// do other things
} else {
// change the state of the button to enable
// do other things
}
}
Đây là cách tôi đã làm nó:
Tạo một ArrayList của EditTexts, sau đó sử dụng vòng lặp for để áp dụng TextWatcher cho tất cả EditTexts, nếu bạn có một hành vi cho tất cả editTexts, sau đó chỉ cần áp dụng nó ở đó, nếu bạn có hành vi cụ thể cho một số editTexts cụ thể, thì bạn có thể sử dụng một tuyên bố để chọn và áp dụng cho các editTexts riêng lẻ.
Đây là mã của tôi:
ArrayList<EditText> editTexts = new ArrayList<>(); // Container list
editText1 = (EditText) findViewById(R.id.editText1);
editText2 = (EditText) findViewById(R.id.editText2);
editText3 = (EditText) findViewById(R.id.editText3);
editTexts.add(editText1); // editTexts[0]
editTexts.add(editText2); // editTexts[1]
editTexts.add(editText3); // editTexts[2]
for (final EditText editText : editTexts) { //need to be final for custom behaviors
editText.addTextChangedListener(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(Editable s) {
//Apply general behavior for all editTexts
if (editText == editTexts.get(1)) {
//Apply custom behavior just for this editText
}
}
});
}
Hi vọng điêu nay co ich
onTextChanged
trên EditText. Thêm một onFocusChange
cho nhiều widget đơn giản hơn nhiều, vì nó đã truyền đối tượng người gửi bằng lệnh gọi phương thức. Sau đó, bạn có thể kiểm tra đối tượng nào đã kích hoạt cuộc gọi và xử lý nó từ đó.