Differences between TextWatcher 's onTextChanged, beforeTextChanged and afterTextChanged
onTextChanged
runs during the text changing.
afterTextChanged
runs immediately after the text is changed.
beforeTextChanged
runs the instant before the text is changed.
Depending on when you want to assign variables or do things, you may want to run the code the instant before the change, or the instant after.
Here is an example of this:
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();
}
});
}
In this case, let's say you changed the text from "h" to "hi", the output would be:
before: "h"
on: "hi"
after: "hi"
Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
These events are called in the following order:
beforeTextChanged(CharSequence s, int start, int count, int after).
This means that the characters are about to be replaced with some new text. The text is uneditable.
Use: when you need to take a look at the old text which is about to change.onTextChanged(CharSequence s, int start, int before, int count).
Changes have been made, some characters have just been replaced. The text is uneditable.
Use: when you need to see which characters in the text are new.afterTextChanged(Editable s).
The same as above, except now the text is editable.
Use: when you need to see and possibly edit the new text.
If I'm just listening for changes in EditText
, I won't need to use the first two methods at all. I will just receive new values in the third method and correct new text if needed. However, if I had to track down exact changes which happen to the values, I would use the first two methods. If I also had a need to edit the text after listening to the changes, I would do that in the third method.
onTextChanged vs afterTextChanged in Android - Live examples needed
I found an explanation to this on Android Dev Portal
http://developer.android.com/reference/android/text/TextWatcher.html
**abstract void afterTextChanged(Editable s)**
This method is called to notify you that, somewhere within s, the text has been changed.
**abstract void beforeTextChanged(CharSequence s, int start, int count, int after)**
This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after.
**abstract void onTextChanged(CharSequence s, int start, int before, int count)**
This method is called to notify you that, within s, the count characters beginning at start have just replaced old text that had length before.
So, the differences between the two are:
- I can change my text using
afterTextChanged
whileonTextChanged
does not allow me to do that - onTextChanged gives me the offset of what changed where, while afterTextChanged does not
How to know a delete operation occurred in EditText in Android?
There is no CallBack for Removing charactor directly !!
But each time you add any text or edit your EditText text all of TextWatcher CallBacks called Respectively
(1-beforeTextChanged , 2-onTextChanged, 3-afterTextChanged)
Therefore you can check delete operation in all of them as below.
Notice that you don't need to check delete operation in all callbacks .
There are 3 ways to understand delete operation in TextWatcher in 3 TextWatcher CallBacks and each of them can solve your problem :)
.I think it is better for you to know about some of TextWatcher callBacks arguments.
As @ikerfah said
- start is the start index that is about to be deleted
- count is the length of the text that is about to be deleted
- after is the length of the text that is about to be added
Ways :
- beforeTextChanged: you compare after argument with count argument .
- onTextChanged: you declare a field in your activity or fragment and fill the field each time
onTextChanged
called . compare your
field which is previous EditText count with count argument which is
current EditTextCount; - afterTextChanged: It is pretty like
onTextChanged
listener but just you use length instead of count.
Change Your Final addTextChangedListener link below:
yourEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
if (after < count) {
// delete character action have done
// do what ever you want
Log.d("MainActivityTag", "Character deleted");
}
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
//mPreviousCount count is fied
if (mPreviousCount > count) {
// delete character action have done
// do what ever you want
Log.d("MainActivityTag", "Character deleted");
}
mPreviousCount=count;
}
@Override
public void afterTextChanged(Editable editable) {
Log.d("MainActivityTag",editable.toString());
int length=editable.length();
//mPreviousLength is a field
if (mPreviousLength>length)
{
// delete character action have done
// do what ever you want
Log.d("MainActivityTag", "Character deleted");
}
mPreviousLength=length;
}
});
How can I get new entered value on EditText with TextWatcher
By start
andcount
parameters in the onTextChanged
method, you can calculate and get the new typed value.
onTextChanged
This method is called to notify you that, within
s
, thecount
characters beginning atstart
have just replaced old text that had
lengthbefore
. It is an error to attempt to make changes tos
from
this callback.
So you can:
public class MyTextWatcher implements TextWatcher {
private String newTypedString = "";
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
newTypedString = s.subSequence(start, start + count).toString().trim();
}
@Override
public void afterTextChanged(Editable s) {
}
}
Inconsistent onTextChanged() behaviour
While I don't have an explanation why it happens with 3 digits, I found out that there is no guarantee when offesets will be invalidated at all. Check this this
"You are not told where the change took place because other afterTextChanged() methods may already have made other changes and invalidated the offsets. But if you need to know here, you can use Spannable#setSpan
in onTextChanged(CharSequence, int, int, int)
to mark your place and then look up from here where the span ended up."
One possible implemetation of TextWatcher
would be this one.
That way you will have the proper begin and end indexes.
Related Topics
How to Create a Drop-Down List
Displaying Emoticons in Android
Turn on Location Services Without Navigating to Settings Page
Display Back Button on Action Bar
Is There a Real Solution to Debug Cordova Apps
Recyclerview Itemtouchhelper Buttons on Swipe
Actionbar Up Navigation with Fragments
Refreshing Data in Recyclerview and Keeping Its Scroll Position
Android Automatic Horizontally Scrolling Textview
How to Programmatically Scroll a Scroll View to a Specific Edit Text
Illegalargumentexception: Navigation Destination Xxx Is Unknown to This Navcontroller
Calculating Distance Between Two Geographic Locations
Android.View.Inflateexception: Binary Xml File: Error Inflating Class Fragment
Android HTML5 Input Type="Password" and Numeric Keyboard
CSS - Sibling Selector Not Working in Android
Android Checkbox Listview Select All (Disable/Enable)