The parameters for beforeTextChanged
and onTextChanged
are a little hard to understand at first. It may be helpful to see them being used in an example. Watch the following demonstration a few times. Pay attention to the counts.
- The red highlight is the old text that is about to be replaced by the green text.
- The green highlight is the new text that just replaced the red text.
beforeTextChanged
start
is the start index of the red highlighted text (that is about to be deleted)
count
is the length of the red highlighted text (that is about to be deleted)
after
is the length of the green highlighted text (that is about to be added)
onTextChanged
start
is the start index of the green highlighted text (that just got added).
This is the same as the start
of beforeTextChanged
.
before
is the length of the red highlighted text (that just got deleted).
This is the same as the count
of beforeTextChanged
.
count
is the length of the green highlighted text (that just got added).
This is the same as the after
of beforeTextChanged
.
afterTextChanged
editable
is the editable text from the EditText. You are allowed to change it here. Doing so will trigger all the TextWatcher
events again.
- You are not given any information about what was changed. If you want to know, you can set a span in
onTextChanged
and then look up the span here.
When to use which?
If you want to observe the changes being made, use beforeTextChanged()
or onTextChanged()
. You are not allowed to change the CharSequence
text in either of these methods, though.
If you want to further modify the text after it was changed, do it in afterTextChanged()
.
Code
Here is the code if you want to play around with it yourself.
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>