Domanda

Voglio implementare l'interfaccia TextWatcher per più di un campi EditText. Attualmente sto usando:

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

quindi sostituendo i metodi nella mia attività:

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 
}

bene Tuttavia, questo funziona, ma sto cercando altri modi in modo da poter identificare in modo esplicito che, in quale campo EditText la SoftKeyboard è attualmente focalizzata.

È stato utile?

Soluzione

Soluzione suggerita in di @Sebastian Roth risposta non è un'istanza di TextWatcher per qualche EditTexts. Si tratta di una classe e n istanze di quella classe per n EditTexts.

Ogni EditText ha il suo Spannable. Gli eventi di TextWatcher ha questo Spannable come parametro di s. Posso controllare il loro hashCode (ID univoco di ogni oggetto). myEditText1.getText () restituisce tale Spannable. Quindi, se il myEditText1.getText().hashCode() uguale con s.hashCode() significa che s appartiene alla myEditText1

Quindi, se si vuole avere un'istanza di TextWatcher per qualche EditTexts si dovrebbe usare questo:

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

};

e

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

Altri suggerimenti

Vorrei fare in questo modo:

@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) {
    }
}

Uso di "CustomTextWatcher" idea, ho fatto che

1) Crated una nuova interfaccia 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) creato e utilizzato EditTextExtended invece di EditText (nel mio caso):

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) Quindi, in cui è necessario scrivere questo codice:

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

4) li usano:

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

Bene, fatemi sapere cosa ne pensate.

- EDIT -

Se si desidera utilizzare solo editables afterTextChanged confrontare:

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

Io uso questa soluzione:

  • Aggiungi metodo che restituisce ascoltatore:

    private TextWatcher getTextWatcher(final EditText editText) {
        return 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) {
                // do what you want with your EditText
                editText.setText("blabla");
            }
    
            @Override
            public void afterTextChanged(Editable editable) {
    
            }
        };
    }
    
  • Aggiungi ascoltatore a più EditText di, si può anche passare altri parametri:

    editText1.addTextChangedListener(getTextWatcher(editText1));
    editText2.addTextChangedListener(getTextWatcher(editText2));
    editText3.addTextChangedListener(getTextWatcher(editText3));
    

Un altro modo per aggirare è quello di aggiungere OnClickListener per EditText e impostare una variabile globale come indicato di seguito

EditText etCurrentEditor;//Global variable

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

Utilizzare questa etCurrentEditor come un riferimento a attualmente editata EditText

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

Sì, è possibile utilizzare più istanze di un TextWatcher personalizzate che contengono il TextView. (TextView è in realtà la classe che ha addTextChangedListener.)

Simile alla soluzione hashCode sopra si può solo controllare se getText()==s. Invece di uno memorizzare tutti i vostri comandi o findViewById più volte, si potrebbe semplicemente eseguire la scansione del contenuto di albero da soli una volta per il controllo che ha il CharSequence.

public TextView findTextView(View v, CharSequence s)
{
   TextView tv;
   ViewGroup vg;
   int i, n;

   if (v instanceof TextView)
   {
      tv = (TextView) v;
      if (tv.getText()==s) return(tv);
   }

   else if (v instanceof ViewGroup)
   {
      vg = (ViewGroup) v;
      n = vg.getChildCount();
      for(i=0;i<n;i++)
      {
         tv = findTextView(vg.getChildAt(i), s);
         if (tv!=null) return(tv);
      }
   }

   return(null);
}

public void afterTextChanged(Editable s)
{
   TextView tv=findTextView(findViewById(android.R.id.content), s);
   if (tv==null) return;
   switch(tv.getId())
   {
      case R.id.path:
         break;
      case  R.id.title:
         break;
   }
}

Naturalmente si potrebbe anche usare findTextView all'interno beforeTextChanged e onTextChanged.

Globale Una classe per tutte le attività.

CustomTextWatcher.java

package org.logicbridge.freshclub.customizedItems;

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
    public class CustomTextWatcher implements TextWatcher {
        private EditText mEditText;
        Context context;

        public CustomTextWatcher(EditText e, Context context) {
            mEditText = e;
            this.context = context;
        }

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

        }
    }

Ho implementato come:

edittext1.addTextChangedListener(this);
edittext2.addTextChangedListener(this);
edittext3.addTextChangedListener(this);

e

@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    if(edittext1.hasFocus()){
        //text changed for edittext1
    }else if(edittext2.hasFocus()){
        //text changed for edittext2
    }else {
        //text changed for edittext3
    }
}

@Override
public void afterTextChanged(Editable editable) {

}

Dopo provare diversi modi per raggiungere questo obiettivo, ho trovato il modo giusto usando EditText.isFocused() per distinguere gli uni agli altri. Ad esempio:

    private class OnTextChangedListener implements 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) {
        if (edtName.isFocused()) {
            //do something
        } else if (edtEmail.isFocused()) {
            //do something
        } else if (edtContent.isFocused()) {
             //do something
        }
    }
}

Si può sempre definire TextWatcher come parametro per method.This addTextChangedListener modo è possibile avere più definizioni per ogni modifica del testo.

codici hash basta confrontare della EditText e stringa come utilizzando hashCode () metodo

@Override
public void afterTextChanged(Editable s) {

    if (editext.getText().hashCode() == s.hashCode()){
        type1Total(type1List);
    }

}

Questo è quello che ho fatto ...

private TextWatcher textWatcher = 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) {

        if (editText1.getText().length() > 0
                && editText2.getText().length() > 0
                && editText3.getText().length() > 0) {

            button.setEnabled(true);
        } else {

            button.setEnabled(false);
        }

    }

    @Override
    public void afterTextChanged(Editable s) {

    }

Poi appena aggiunto il TextWatcher ad ogni EditText nel metodo onCreate e anche mantenuto il pulsante setEnabled (false) per impostazione predefinita qui.

button.setEnabled(false); 

    editText1.addTextChangedListener(textWatcher);
    editText2.addTextChangedListener(textWatcher);
    editText3.addTextChangedListener(textWatcher);

Si può fare questo per ottenere l'id del montaggio testi. Non è testato, ma fatemi sapere se funziona.

//setting textWatcher for the editText
textWatcher(owner_name);


public void textWatcher(final EditText editText){

    TextWatcher watcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

           if(editText.getId()==R.id.your_id){
             //Do something
           }   
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
          if(editText.getId()==R.id.your_id){
          //Do something
          }
        }

        @Override
        public void afterTextChanged(Editable s) { }
    };

    editText.addTextChangedListener(watcher);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top