如何使用单个TextWatcher多个EditTexts?

时间:2011-04-18 12:20:31

标签: android textwatcher

我的视图布局中有三个EditText小部件。有没有办法为所有三个TextWatcher使用一个EditTexts

13 个答案:

答案 0 :(得分:186)

我刚遇到这个问题。我通过创建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));

答案 1 :(得分:36)

如果您只想使用afterTextChanged比较editables:

@Override
public void afterTextChanged(Editable editable) {
    if (editable == mEditText1.getEditableText()) {
        // DO STH
    } else if (editable == mEditText2.getEditableText()) {
        // DO STH
    }
}

答案 2 :(得分:10)

它可以使用此代码

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);

        }
    };

然后在oncreate中添加

  mInputText.addTextChangedListener(watcher);
        e2.addTextChangedListener(watcher);
        e3.addTextChangedListener(watcher);
        e4.addTextChangedListener(watcher);

答案 3 :(得分:9)

MultiTextWatcher实施

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
                }
            });

答案 4 :(得分:6)

如果您想使用 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 
    }
}

答案 5 :(得分:5)

让您的类继承自Activity并实现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
        }
    }

答案 6 :(得分:5)

我知道这是一个老问题,而且有正确的决定。我会写自己的,也许会帮助别人。

模拟我们有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);
    }
}

看起来非常简单,现在

CustomTextWatcher.class

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);
    }
  }
}

我会添加一个布局,所以你不要浪费时间

multi_edit_text.xml

<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>

答案 7 :(得分:3)

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);

答案 8 :(得分:0)

我是这样做的:

创建一个EditTexts的ArrayList,然后使用for循环为所有EditTexts应用TextWatcher,如果你有一个所有editTexts的行为,那么只需在那里应用它,如果你对某些特定的editTexts有特定的行为,那么你可以使用if语句选择并应用于各个editTexts ......这是我的代码:

    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                           
                }
            }
        });

    }

希望这有帮助

答案 9 :(得分:0)

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;
                 }
             }   
         }
     }
}

答案 10 :(得分:0)

我知道这个问题很老,但是我想分享我的一个解决方案(在Kotlin中)。我的解决方案是@Shwarz Andrei的答案的改进,我的理由是如果你想操纵更多的东西/对象。

不是将list of EditTextsa Button都作为参数传递,而是只传递list of editText。然后在你的自定义类中,你将实现一个lambda:

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 
           }
       }
   }
  
    

因此,每次调用lambda的一些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 
            }
        }

答案 11 :(得分:0)

这是我对Kotlin的解决方案。您只需使用引用相等(===)来检查同一对象,即可正常工作。

.menu_link:hover {
    color: black;
    background-color: beige;
}

答案 12 :(得分:0)

对于Kotlin代码:

设置文本观察器 //在create里面

 etFirst.addTextChangedListener(generalTextWatcher)
 etFirstSecond.addTextChangedListener(generalTextWatcher)

常规文本监视程序的make函数 //在外部创建

 private val generalTextWatcher: TextWatcher = object : TextWatcher {
        override fun onTextChanged(
            s: CharSequence, start: Int, before: Int,
            count: Int
        ) {
            when (s.hashCode()) {
                etFirst.text.hashCode() -> { /* take value for first text */ }
                etSecond.text.hashCode() -> { /* take value for second text */ }
            }
        }

        override fun beforeTextChanged(
            s: CharSequence, start: Int, count: Int,
            after: Int
        ) {

        }

        override fun afterTextChanged(s: Editable) {

        }
    }