Android на слушателя изменения текста



у меня есть ситуация, когда есть два поля. field1 и field2. Все, что я хочу
делать пусто field2, когда field1 изменяется и наоборот. Так что в конце только
одно поле имеет содержание на нем.



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


он отлично работает, если я прикрепляю addTextChangedListener до field1 только, но когда
Я делаю это для обоих полей приложение аварийно завершает работу. Очевидно, потому, что они пытаются изменить
друг друга на неопределенный срок. Один раз field1 изменения очищает field2 на данный момент
field2 изменяется, так что это будет ясно field1 и так далее...



может ли кто-нибудь предложить какое-либо решение?

691   7  

7 ответов:

вы можете добавить проверку, чтобы очистить только тогда, когда текст в поле не пуст (т. е. когда длина отличается от 0).

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

документация TextWatcherздесь.

также, Пожалуйста, уважайте соглашения об именах.

Я знаю, что это старый, но кто-то может сталкивался с этим когда-нибудь еще.

У меня была аналогичная проблема, когда я вызывал setText на EditText, а onTextChanged вызывался, когда я этого не хотел. Мое первое решение состояло в том, чтобы написать некоторый код после вызова setText (), чтобы отменить ущерб, нанесенный слушателем. Но это было не очень элегантно. После проведения некоторых исследований и тестирования я обнаружил, что с помощью getText().clear () очищает текст во многом так же, как setText (""), но поскольку он не устанавливает текст, слушатель не вызывается, так что это решило мою проблему. Я переключил все мои вызовы setText("") на getText().ясно () и мне больше не нужны бинты, так что, возможно, это тоже решит вашу проблему.

попробуйте это:

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

немного поздно ответа, но вот многоразовое решение:

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

поэтому, когда используется выше, любой setText() вызовы, происходящие в TextWatcher, не приведут к повторному вызову TextWatcher:

/**
 * 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) {
    }
}

проверьте строку перед установкой другой EditText пустое. если Field1 пусто тогда зачем нужно снова менять на ( "")? таким образом, вы можете проверить размер вашей строки с ы.длина() или любое другое решение

другой способ, которым вы можете проверить длину строки:

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

Я также столкнулся с той же проблемой и продолжаю получать полные исключения стека, и я пришел со следующим решением.

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

объявленный изначально логический skipOnChange = false;

Если вы используете Kotlin для разработки Android, то вы можете добавить текст изменения слушателя с помощью этого кода:

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

вы также можете использовать метод hasFocus ():

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

протестировал это для задания колледжа, над которым я работал, чтобы преобразовать температурные шкалы, когда пользователь вводил их. Работал отлично, и это намного проще.

Comments

    Ничего не найдено.