Различия между TextWatcher onTextChanged, beforeTextChanged и afterTextChanged

В моем проекте Android мне пришлось добавить TextChangedListener (TextWatcher) в представление редактирования текста. И есть три части:

  • onTextChanged()
  • beforeTextChanged()
  • afterTextChanged()

Каковы различия этих трех? Я должен был осуществить поиск таблицы по ключевому слушателю, и для моего случая все эти три выглядели одинаково. Также они функционировали одинаково. Когда я ввожу часть названия продукта, таблица перерисовывается только теми продуктами, которые содержат введенный текст. Но я использовал часть afterTextChanged(). Мой код:

EditProduct.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            // TODO Auto-generated method stub

            // System.out.println("onTextChanged"+s);
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub
            // System.out.println("beforeTextChanged"+s);
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            // System.out.println("afterTextChanged"+s);

            String new_prx = s.toString();

            System.out.println(s);
            mini_productList = new ArrayList<Product>();

            // mini_productList
            int count = 0;
            if (new_prx.equals("")) {

                loadtableProducts(productList);

            } else {

                for (int i = 0; i < productList.size(); i++) {

                    if (productList.get(i).getDescription().toString()
                            .substring(0, (new_prx.length()))
                            .equalsIgnoreCase(new_prx)) {
                        mini_productList.add(productList.get(i));
                        count++;

                    }
                }

                loadtableProducts(mini_productList);
            }
        }
    });

Так может кто-нибудь дать мне объяснение этих трех?

Ответ 1

onTextChanged выполняется во время изменения текста.

afterTextChanged выполняется сразу после изменения текста.

beforeTextChanged запускает момент перед изменением текста.

В зависимости от того, когда вы хотите назначить переменные или что-то делать, вы можете запустить код за мгновение до изменения или через мгновение после.

Вот пример:

String afterTextChanged = "";
String beforeTextChanged = "";
String onTextChanged = "";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et = (EditText)findViewById(R.id.editText);

    et.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int st, int b, int c) 
        {
            onTextChanged = et.getText().toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int st, int c, int a) 
        {
            beforeTextChanged = et.getText().toString();
        }

        @Override
        public void afterTextChanged(Editable s) 
        {
            afterTextChanged = et.getText().toString();
            Toast.makeText(Activity.this, "before: " + beforeTextChanged
                                           + '\n' + "on: " + onTextChanged 
                                           + '\n' + "after: " + afterTextChanged
                           ,Toast.LENGTH_SHORT).show();
        }
    });
}

В этом случае, скажем, вы изменили текст с "h" на "hi", результатом будет:

до: "h"
по: "привет"
после: "привет"

Ответ 2

Параметры для beforeTextChanged и onTextChanged сначала немного трудно понять. Может быть полезно увидеть, как они используются в примере. Несколько раз смотрите следующую демонстрацию. Обратите внимание на подсчеты.

  • Значок красный - это старый текст, который должен быть заменен зеленым текстом.
  • Основной ярлык зеленый - это новый текст, который только что заменил красный текст.

введите описание изображения здесь

beforeTextChanged

  • start - начальный индекс красного выделенного текста (который должен быть удален)
  • count - длина выделенного текста красного (который должен быть удален)
  • after - длина выделенного текста зеленый (который должен быть добавлен)

OnTextChanged

  • start - начальный индекс зеленого выделенного текста (который только что добавлен).
    Это то же самое, что и start beforeTextChanged.
  • before - это длина выделенного текста красного (который только что удалился).
    Это то же самое, что и count beforeTextChanged.
  • count - это длина выделенного текста зеленый (который только что добавлен).
    Это то же самое, что и after beforeTextChanged.

afterTextChanged

  • editable - редактируемый текст из EditText. Вы можете изменить его здесь. Это приведет к повторению всех событий TextWatcher.
  • Вам не предоставлена ​​информация о том, что было изменено. Если вы хотите знать, вы можете установить интервал в onTextChanged, а затем найти здесь диапазон.

Когда использовать какой?

Если вы хотите наблюдать за внесенными изменениями, используйте beforeTextChanged() или onTextChanged(). Однако вам не разрешено изменять текст CharSequence в любом из этих методов.

Если вы хотите изменить текст после его изменения, сделайте это в afterTextChanged().

Код

Вот код, если вы хотите поиграть с ним самостоятельно.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    final static int RED_COLOR = Color.parseColor("#fb7373");
    final static int GREEN_COLOR = Color.parseColor("#40de83");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = findViewById(R.id.editText);
        final TextView tvBeforeText = findViewById(R.id.tvBeforeText);
        final TextView tvBeforeNumbers = findViewById(R.id.tvBeforeNumbers);
        final TextView tvAfterText = findViewById(R.id.tvAfterText);
        final TextView tvAfterNumbers = findViewById(R.id.tvAfterNumbers);

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                SpannableString spannableString = new SpannableString(s);
                BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(RED_COLOR);
                spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                tvBeforeText.setText(spannableString);
                tvBeforeNumbers.setText("start=" + start + "  count=" + count + " after=" + after);
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                SpannableString spannableString = new SpannableString(s);
                BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(GREEN_COLOR);
                spannableString.setSpan(backgroundSpan, start, start + count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                tvAfterText.setText(spannableString);
                tvAfterNumbers.setText("start=" + start + " before=" + before + " count=" + count);
            }

            @Override
            public void afterTextChanged(Editable s) {
                Log.i("TAG", "afterTextChanged: " + s);
            }
        });
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:text="beforeTextChanged" />

    <TextView
        android:id="@+id/tvBeforeText"
        android:textSize="17sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tvBeforeNumbers"
        android:textSize="17sp"
        android:text="start=0 count=0 after=0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:layout_marginTop="20dp"
        android:text="onTextChanged" />

    <TextView
        android:id="@+id/tvAfterText"
        android:textSize="17sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tvAfterNumbers"
        android:textSize="17sp"
        android:text="start=0 count=0 after=0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Ответ 3

Android TextChangedListener - это один из видов триггеров, который вызывается при изменении текста поля ввода.

TextChangedListener имеет три события.

1.beforeTextChanged: Это означает, что символы будут заменены новым текстом. Текст не может быть изменен. Это событие используется, когда вам нужно взглянуть на старый текст, который вот-вот изменится.

2.onTextChanged: Были внесены изменения, некоторые символы только что были заменены. Текст не может быть изменен. Это событие используется, когда вам нужно увидеть, какие символы в тексте являются новыми.

3.afterTextChanged: То же, что и выше, за исключением того, что текст доступен для редактирования. Это событие используется, когда вам нужно увидеть и, возможно, отредактировать новый текст.

Ответ 4

  • abstract void afterTextChanged(Editable s)

Этот метод вызывается, чтобы уведомить вас о том, что где-то в s текст был изменен.

  • abstract void beforeTextChanged(CharSequence s, int start, int count, int after)

Этот метод вызывается, чтобы уведомить вас о том, что в пределах s счетчик символы, начинающиеся с начала, будут заменены новым текстом с длиной после.

  • abstract void onTextChanged(CharSequence s, int start, int before, int count)

Этот метод вызывается, чтобы уведомить вас о том, что в пределах s счетчик символы, начинающиеся с начала, только что заменили старый текст, который длина до.

Вы можете узнать здесь.

Ответ 5

  • afterTextChanged (редактируемый) - этот метод вызывается, когда текст был изменен. Поскольку любые сделанные вами изменения метод, который будет вызываться снова рекурсивно, вы должны быть внимательны выполняя операции здесь, иначе это может привести к бесконечному циклу.

  • beforeTextChanged (CharSequence s, int start, int count, int after) - Этот метод вызывается, чтобы уведомить вас о том, что в пределах s счетчик символы, начинающиеся с начала, будут заменены новым текстом с длиной после. Ошибка при попытке внести изменения в s из этот обратный вызов.

  • onTextChanged (CharSequence s, int start, int before, int count) - этот метод вызывается, чтобы уведомить вас о том, что в пределах s счетчик символы, начинающиеся с начала, только что заменили старый текст, который длина перед тем. Ошибка при попытке внести изменения в s из этот обратный вызов.