Различия между onTextChanged TextWatcher, 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);
}
}
});
Так может кто-нибудь дать мне объяснение этих трех?
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" на "hi", результат будет:
до: "ч"
на: "привет"
после: "привет"
Параметры для 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>
Android TextChangedListener
это один из видов триггера, который вызывается при изменении текста поля ввода.
TextChangedListener
имеет три события.
1.beforeTextChanged: это означает, что символы должны быть заменены новым текстом. Текст не редактируется. Это событие используется, когда вам нужно взглянуть на старый текст, который собирается измениться.
2.onTextChanged: внесены изменения, некоторые символы только что заменены. Текст не редактируется. Это событие используется, когда вам нужно увидеть, какие символы в тексте являются новыми.
3.afterTextChanged: то же, что и выше, за исключением того, что теперь текст редактируемый. Это событие используется, когда вам нужно увидеть и, возможно, отредактировать новый текст.
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 символы подсчета, начинающиеся с начала, только что заменили старый текст, который имел длину ранее.
Вы можете больше узнать здесь.
afterTextChanged (Editable s) - этот метод вызывается, когда текст был изменен. Поскольку любые внесенные вами изменения приведут к рекурсивному вызову этого метода, вы должны внимательно следить за выполнением операций здесь, иначе это может привести к бесконечному циклу.
beforeTextChanged (CharSequence s, int start, int count, int after) - Этот метод вызывается, чтобы уведомить вас о том, что в пределах s символы подсчета, начинающиеся с начала, должны быть заменены новым текстом с длиной после. Ошибка при попытке внести изменения в s из этого обратного вызова.
onTextChanged (CharSequence s, int start, int before, int count) - этот метод вызывается, чтобы уведомить вас о том, что в пределах s символы count, начинающиеся с начала, только что заменили старый текст, длина которого была раньше. Ошибка при попытке внести изменения в s из этого обратного вызова.