it-swarm.com.de

android bei Text Change Listener

Ich habe eine Situation, in der es zwei Felder gibt. field1 und field2. Alles, was ich tun möchte, ist leer field2, wenn field1 geändert wird, und umgekehrt. Am Ende hat also nur ein Feld Inhalt.

field1 = (EditText)findViewById(R.id.field1);
field2 = (EditText)findViewById(R.id.field2);

field1.addTextChangedListener(new TextWatcher() {

   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) {
      field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   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) {
     field1.setText("");
   }
  });

Es funktioniert einwandfrei, wenn ich addTextChangedListener nur an field1 anhänge, aber wenn ich das für beide Felder mache, stürzt die App ab. Offensichtlich, weil sie versuchen, sich auf unbestimmte Zeit zu verändern. Sobald field1 sich ändert, wird field2 in diesem Moment gelöscht field2 wird geändert, so dass field1 gelöscht wird und so weiter ...

Kann jemand eine Lösung vorschlagen?

211
inrob

Sie können ein Häkchen hinzufügen, um nur zu löschen, wenn der Text im Feld nicht leer ist (d. H. Wenn die Länge nicht 0 ist).

field1.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
        field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
         field1.setText("");
   }
  });

Dokumentation für TextWatcherhier .

Bitte beachten Sie auch Namenskonventionen .

385
user2336315

Ich weiß, das ist alt, aber irgendwann könnte jemand darauf stoßen.

Ich hatte ein ähnliches Problem, bei dem ich setText für einen EditText aufrief und onTextChanged aufgerufen wurde, wenn ich es nicht wollte. Meine erste Lösung bestand darin, nach dem Aufruf von setText () Code zu schreiben, um den vom Listener verursachten Schaden rückgängig zu machen. Das war aber nicht sehr elegant. Nach einigen Recherchen und Tests stellte ich fest, dass getText (). Clear () den Text auf die gleiche Weise löscht wie setText (""), aber da der Text nicht gesetzt wird, wird der Listener nicht aufgerufen mein problem gelöst. Ich habe alle meine setText ("") -Aufrufe auf getText (). Clear () umgestellt und brauchte die Bandagen nicht mehr. Vielleicht löst das auch Ihr Problem.

Versuche dies:

Field1 = (EditText)findViewById(R.id.field1);
Field2 = (EditText)findViewById(R.id.field2);

Field1.addTextChangedListener(new TextWatcher() {

   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) {
      Field2.getText().clear();
   }
  });

Field2.addTextChangedListener(new TextWatcher() {

   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) {
     Field1.getText().clear();
   }
  });
16
BobVicktor

Wenn Sie Kotlin für die Android Entwicklung verwenden, können Sie TextChangedListener() mit diesem Code hinzufügen:

myTextField.addTextChangedListener(object : TextWatcher{
        override fun afterTextChanged(s: Editable?) {}

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

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    })
8
iHulk

Ich habe auch dasselbe Problem und bekomme immer wieder stapelweise Ausnahmen und ich komme mit der folgenden Lösung.

    edt_amnt_sent.addTextChangedListener(new TextWatcher() {    
        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try {
                //method
                }
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });

    edt_amnt_receive.addTextChangedListener(new TextWatcher() {


        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try 
            {
                //method
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });

ursprünglich als boolean deklariert skipOnChange = false;

5
Sumit

Eine etwas verspätete Antwort, aber hier ist eine wiederverwendbare Lösung:

/**
 * An extension of TextWatcher which stops further callbacks being called as 
 * a result of a change happening within the callbacks themselves.
 */
public abstract class EditableTextWatcher implements TextWatcher {

    private boolean editing;

    @Override
    public final void beforeTextChanged(CharSequence s, int start, 
                                                    int count, int after) {
        if (editing)
            return;

        editing = true;
        try {
            beforeTextChange(s, start, count, after);
        } finally {
            editing = false;
        }
    }

    protected abstract void beforeTextChange(CharSequence s, int start, 
                                                     int count, int after);

    @Override
    public final void onTextChanged(CharSequence s, int start, 
                                                int before, int count) {
        if (editing)
            return;

        editing = true;
        try {
            onTextChange(s, start, before, count);
        } finally {
            editing = false;
        }
    }

    protected abstract void onTextChange(CharSequence s, int start, 
                                            int before, int count);

    @Override
    public final void afterTextChanged(Editable s) {
        if (editing)
            return;

        editing = true;
        try {
            afterTextChange(s);
        } finally {
            editing = false;
        }
    }

    public boolean isEditing() {
        return editing;
    }

    protected abstract void afterTextChange(Editable s);
}

Wenn also das oben Genannte verwendet wird, führen alle setText() Aufrufe, die im TextWatcher stattfinden, nicht dazu, dass der TextWatcher erneut aufgerufen wird:

/**
 * A setText() call in any of the callbacks below will not result in TextWatcher being 
 * called again.
 */
public class MyTextWatcher extends EditableTextWatcher {

    @Override
    protected void beforeTextChange(CharSequence s, int start, int count, int after) {
    }

    @Override
    protected void onTextChange(CharSequence s, int start, int before, int count) {
    }

    @Override
    protected void afterTextChange(Editable s) {
    }
}
5
Eurig Jones

Sie können auch die Methode hasFocus () verwenden:

public void onTextChanged(CharSequence s, int start,
     int before, int count) {
     if (Field2.hasfocus()){
         Field1.setText("");
     }
   }

Getestet für eine College-Aufgabe, an der ich gearbeitet habe, um Temperaturskalen während der Eingabe durch den Benutzer umzuwandeln. Perfekt funktioniert, und es ist viel einfacher.

4
renam

überprüfen Sie den String, bevor Sie einen anderen EditText auf leer setzen. Wenn Field1 leer ist, warum muss dann erneut auf ("") gewechselt werden? So können Sie die Größe Ihres Strings mit s.lenght () oder einer anderen Lösung überprüfen

eine andere Möglichkeit, die Länge eines Strings zu überprüfen, ist:

String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}
3