ฉันมีEditText
วิดเจ็ตสามรายการในเค้าโครงมุมมองของฉัน มีวิธีใช้ single TextWatcher
สำหรับทั้งสามEditTexts
หรือไม่?
ฉันมีEditText
วิดเจ็ตสามรายการในเค้าโครงมุมมองของฉัน มีวิธีใช้ single TextWatcher
สำหรับทั้งสามEditTexts
หรือไม่?
คำตอบ:
ฉันเพิ่งเจอปัญหานี้ ฉันแก้ไขได้โดยการสร้างการใช้งานคลาสภายในTextWatcher
ซึ่งใช้ View เป็นอาร์กิวเมนต์ จากนั้นในการใช้งานวิธีการเพียงแค่เปิดมุมมองเพื่อดูว่าEditable
มาจากไหน
ประกาศ:
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;
}
}
}
การใช้งาน:
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
คำตอบนี้ไม่ได้ เป็น 3 อินสแตนซ์ของคลาส TextWatcher เดียว TextWatchers ที่แยกกัน 3 ตัวจึงควบคุม 3 EditTexts
หากคุณต้องการใช้เฉพาะ afterTextChanged เปรียบเทียบการแก้ไข:
@Override
public void afterTextChanged(Editable editable) {
if (editable == mEditText1.getEditableText()) {
// DO STH
} else if (editable == mEditText2.getEditableText()) {
// DO STH
}
}
==
.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
การเปลี่ยนแปลงมาจากไหน
หากคุณต้องการใช้onTextChangedเปรียบเทียบhashCode()
ด้านล่าง -
@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
}
}
หรือ
หากคุณต้องการใช้afterTextChangedเปรียบเทียบEditable
ด้านล่าง -
@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
}
}
มันจะทำงานกับรหัสนี้
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);
}
};
จากนั้นเพิ่มสิ่งนี้ในการสร้าง
mInputText.addTextChangedListener(watcher);
e2.addTextChangedListener(watcher);
e3.addTextChangedListener(watcher);
e4.addTextChangedListener(watcher);
ฉันรู้ว่านี่เป็นปัญหาเก่าและมีการตัดสินใจที่ถูกต้อง ฉันจะเขียนของพวกเขาเองบางทีมันอาจจะช่วยใครบางคนได้
การจำลองตัวอย่างคลาสสิกที่เรามี N EditText และเราต้องการแสดงปุ่มหากมีการเติมฟิลด์ทั้งหมด ตัวอย่างนี้เหมาะสมโดยเฉพาะอย่างยิ่งหากใช้ตัวตรวจสอบความถูกต้องเพิ่มเติมสำหรับแต่ละตัว
ฉันทำตัวอย่างที่เกี่ยวข้องกับปัญหา แต่คุณสามารถทำชุดใดก็ได้
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);
}
}
ตอนนี้ดูง่ายมาก
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);
}
}
}
ฉันจะเพิ่มเค้าโครงเพื่อให้คุณไม่ต้องเสียเวลา
<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>
ให้ชั้นเรียนของคุณสืบทอดจากกิจกรรมและใช้ TextWatcher
จากนั้นด้วยความมหัศจรรย์ของความหลากหลายคุณเพียงแค่สมัครเข้าร่วมกิจกรรม
สิ่งนี้จะไม่บอกคุณว่า TextEdit เปลี่ยนไปอย่างไรอย่างไรก็ตามการใช้การรวมกันของสิ่งนี้และคำตอบของSky Kelseyคุณสามารถแยกแยะได้อย่างดี
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) {
}
};
แล้ว:
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;
}
}
}
}
}
นี่คือทางออกของฉันสำหรับคอตลิน คุณสามารถใช้ความเท่าเทียมกันของการอ้างอิง (===) เพื่อตรวจสอบวัตถุเดียวกันและทำงานได้อย่างสมบูรณ์
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)
ฉันรู้ว่าคำถามนี้เก่า แต่ฉันต้องการแบ่งปันหนึ่งในวิธีแก้ปัญหาของฉัน (ใน Kotlin) ทางออกของฉันคือการปรับปรุงคำตอบของ @Shwarz Andrei เหตุผลของฉันคือถ้าคุณต้องการจัดการสิ่ง / วัตถุเพิ่มเติม
แทนที่จะส่งทั้งสองlist of EditTexts
และa Button
เป็นพารามิเตอร์คุณจะส่งผ่านlist of editText
ไฟล์. จากนั้นภายในคลาสที่คุณกำหนดเองคุณจะใช้แลมด้าเช่น:
var hasFilled:((Boolean)->Unit)? = null
จากนั้นคุณจะตั้งค่าหรือเพิ่มขึ้นภายในไฟล์ 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
}
}
}
ดังนั้นทุกครั้งจึงมีการเปลี่ยนแปลงใน EditText บางตัวแลมด้าของคุณถูกเรียกใช้
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
}
}
นี่คือวิธีที่ฉันทำ:
สร้าง ArrayList ของ EditTexts จากนั้นใช้ for loop เพื่อใช้ TextWatcher สำหรับ EditTexts ทั้งหมดหากคุณมีพฤติกรรมเดียวสำหรับ EditTexts ทั้งหมดจากนั้นนำไปใช้ที่นั่นหากคุณมีพฤติกรรมเฉพาะสำหรับ EditTexts บางอย่างคุณสามารถใช้ if คำสั่งเพื่อเลือกและนำไปใช้กับข้อความแก้ไขแต่ละรายการ
นี่คือรหัสของฉัน:
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
}
}
});
}
หวังว่านี่จะช่วยได้
onTextChanged
ใน EditText การเพิ่มonFocusChange
วิดเจ็ตสำหรับหลาย ๆ วิดเจ็ตนั้นง่ายกว่ามากเนื่องจากส่งผ่านอ็อบเจ็กต์ผู้ส่งด้วยการเรียกใช้เมธอด จากนั้นคุณสามารถตรวจสอบว่าวัตถุใดที่ทำให้เกิดการโทรและจัดการจากที่นั่น