75 votes

TextWatcher pour plusieurs EditText

Je souhaite implémenter l'interface TextWatcher pour plusieurs champs EditText . Actuellement, j'utilise:

 text1.addTextChangedListener(this);
text2.addTextChangedListener(this);
 

puis redéfinissant les méthodes de mon activité:

 public void afterTextChanged(Editable s) {}

public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) 
{
 // do some operation on text of text1 field
 // do some operation on text of text2 field 
}
 

Cependant , cela fonctionne très bien , mais je suis à la recherche d'autres moyens pour que je puisse identifier explicitement que , dans lequel EditText domaine du SoftKeyboard se concentre actuellement.

97voto

breceivemail Points 8024

La solution proposée dans @Sébastien Roth réponse n'est pas une instance de l' TextWatcher pour certains EditTexts. C'est l'une de la classe et de n instances de cette classe pour n EditTexts.

Chaque EditText a son propre Spannable. TextWatchers'événements a ce Spannable comme s paramètre. J'ai vérifier leur hashCode (Id unique de chaque objet). myEditText1.getText() retourne la Spannable. Donc, si l' myEditText1.getText().hashCode() égal à égal avec s.hashCode() cela signifie qu' s appartient myEditText1

Donc, si vous voulez avoir qu'une seule instance de l' TextWatcher pour certains EditTexts vous devez utiliser:

private TextWatcher generalTextWatcher = new TextWatcher() {    

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

        if (myEditText1.getText().hashCode() == s.hashCode())
        {
            myEditText1_onTextChanged(s, start, before, count);
        }
        else if (myEditText2.getText().hashCode() == s.hashCode())
        {
            myEditText2_onTextChanged(s, start, before, count);
        }
    }

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

        if (myEditText1.getText().hashCode() == s.hashCode())
        {
            myEditText1_beforeTextChanged(s, start, count, after);
        }
        else if (myEditText2.getText().hashCode() == s.hashCode())
        {
            myEditText2_beforeTextChanged(s, start, count, after);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        if (myEditText1.getText().hashCode() == s.hashCode())
        {
            myEditText1_afterTextChanged(s);
        }
        else if (myEditText2.getText().hashCode() == s.hashCode())
        {
            myEditText2_afterTextChanged(s);
        }
    }

};

et

myEditText1.addTextChangedListener(generalTextWatcher);
myEditText2.addTextChangedListener(generalTextWatcher);

88voto

Sebastian Roth Points 5091

Je le ferais comme ça:

 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    EditText e = new EditText(this);
    e.addTextChangedListener(new CustomTextWatcher(e));
}

private class CustomTextWatcher implements TextWatcher {
    private EditText mEditText;

    public CustomTextWatcher(EditText e) { 
        mEditText = e;
    }

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

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

    public void afterTextChanged(Editable s) {
    }
}
 

12voto

user3132789 Points 31

en utilisant l'idée "CustomTextWatcher", je l'ai fait

1) Création d'une nouvelle interface TextWatcherListener:

 public interface TextWatcherExtendedListener extends NoCopySpan
{
    public void afterTextChanged(View v, Editable s);

    public void onTextChanged(View v, CharSequence s, int start, int before, int count);

    public void beforeTextChanged(View v, CharSequence s, int start, int count, int after);
}
 

2) Créé et utilisé EditTextExtended au lieu de EditText (dans mon cas):

 public class EditTextExtended extends EditText
{
   private TextWatcherExtendedListener  mListeners = null;

   public EditTextExtended(Context context) 
   {
     super(context);
   }

   public EditTextExtended(Context context, AttributeSet attrs)
   {
      super(context, attrs);
   }

   public EditTextExtended(Context context, AttributeSet attrs, int defStyle)
   {
        super(context, attrs, defStyle);
   }

   public void addTextChangedListener(TextWatcherExtendedListener watcher) 
   {    
       if (mListeners == null) 
       {
           mListeners = watcher;
       }
   }

   public void removeTextChangedListener(TextWatcherExtendedListener watcher) 
   {
       if (mListeners != null) 
       {
           mListeners = null;        
       }
   }

   void  sendBeforeTextChanged(CharSequence text, int start, int before, int after)
   {
       if (mListeners != null) 
       {
           mListeners.beforeTextChanged(this, text, start, before, after);
       }
   }

   void  sendOnTextChanged(CharSequence text, int start, int before,int after) 
   {
       if (mListeners != null) 
       {
           mListeners.onTextChanged(this, text, start, before, after);
       }
   }

   void  sendAfterTextChanged(Editable text) 
   {
       if (mListeners != null)
       {
           mListeners.afterTextChanged(this, text);
       }
   }
}
 

3) Donc, où vous avez besoin d'écrire ce code:

 myEditTextExtended.addTextChangedListener(this) //Let implement TextWatcherExtendedListener methods
 

4) les utiliser:

 @Override
public void onTextChanged(View v, CharSequence s, int start, int before, int count) 
{
   //Tested and works
   //do your stuff  
}


@Override
public void beforeTextChanged(View v, CharSequence s, int start, int count, int after)
{   
     //not yet tested but it should work    
}

@Override
public void afterTextChanged(View v, Editable s) 
{
    //not yet tested but it should work 
}
 

Eh bien, laissez-moi savoir ce que vous en pensez.

12voto

Tomasz Points 128

--MODIFIER--

Si vous voulez utiliser uniquement afterTextChanged, comparez les éditeurs:

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

2voto

Une autre solution consiste à ajouter OnClickListener à EditText et à définir une variable globale comme indiqué ci-dessous

 EditText etCurrentEditor;//Global variable

@Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        if(v instanceof EditText){
            etCurrentEditor=(EditText)v;
        }
    }
 

Utilisez cet etCurrentEditor comme référence au EditText actuellement édité

 @Override
    public void afterTextChanged(Editable editable) {
        // TODO Auto-generated method stub
        switch (etCurrentEditor.getId()) {
        case R.id.EDITTEXTID:
            break;
        default:
            break;
        }
    }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X