Различия между 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);
            }
        }
    });

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


person Samantha Withanage    schedule 29.11.2013    source источник
comment
Эта ветка может оказаться полезной: вопросы/476848/   -  person Abhishek V    schedule 29.11.2013


Ответы (5)


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» на «привет», вывод будет таким:

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

person Michael Yaworski    schedule 29.11.2013
comment
Итак, в чем разница между onTextChanged и afterTextChanged? - person krosshj; 17.11.2018

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

  • Выделенный красным старый текст будет заменен зеленым текстом.
  • Выделенный зеленым новый текст, который только что заменил красный текст.

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

перед текстомизменен

  • start — это начальный индекс выделенного красным текста (который будет удален)
  • count – длина выделенного красным текста (который будет удален)
  • after – длина выделенного зеленым текста (который будет добавлен).

onTextChanged

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

послетекстизменен

  • 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>
person Suragch    schedule 13.11.2017

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

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

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

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

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

person Jigar Pandya    schedule 29.11.2013
comment
что, если мне нужно заботиться об изменении текста, я имею в виду после изменения. Я использовал тот же фрагмент кода, о котором упоминал в afterTextChanged, для каждого из остальных. Это дало мне тот же результат. - person Samantha Withanage; 29.11.2013
comment
Я не понял, что ты пытаешься сказать! ontextchanged и aftertextchange дадут одинаковый результат - person Jigar Pandya; 29.11.2013
comment
Когда вы говорите, что текст редактируемый/не редактируемый, что означает текст? - person Jonas; 18.09.2015
comment
@Jonas, это означает, что параметр i.e.e. в afterTextChanged можно отредактировать или изменить на что-то другое; в то время как его нельзя редактировать или изменить в двух других событиях (onTextChanged и beforeTextChanged).... скорее, в двух других, он просто информирует вас о том, что что-то в этом s изменилось. Он также показывает, насколько изменилось, когда изменение началось и закончилось. - person pasignature; 07.07.2020

  • abstract void afterTextChanged(Editable s)

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

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

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

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

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

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

person Kailash Dabhi    schedule 29.11.2013

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

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

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

person Community    schedule 16.11.2015