Why TextWatcher needed - android

So, after going through some docs regarding TextWatcher, I'm still not too sure why it's actually needed. Any help with real example (no code) will be great. Thanks.

TextWatcher is needed to know if a field text has been changed.
Presume you have a mobile number, and you need to check the length of it. As a standard mobile number should contain 10 digits. You have an error field at the side which will go away once the edittext length will be greater than 10. How will you know that now the length is greater than 10?
To overcome this we have textwatcher method which watch over the edittext field. Generally we will check length of edittext in AfterTextChanged callback and it will work in realtime. After that you can make your logics behind what to do after the length is greater than 10.
This is just an example. There are certain many more ways in which you can use textwatcher.

TextWatcher :
TextWatcher is used to keep watch on the EditText content while user inputs the data. It allows you to keep track on each character when entered on EditText. A Text Watcher is really helpful for scenarios like login/register screen validation.
The TextWatcher have Three method is below :
Method 1 : afterTextChanged(Editable s)
=> This method is called to notify you that, somewhere within s, the text has been changed.
Method 2 : 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.
Method 3 : 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.

Related

Android - Override user edittext input and add characters towards a specific text?

So I'm currently trying to achieve the following: I have one big piece of text not stored in my app yet. I will have one big EditText and what I want to do is when a user touches any key on the keyboard, a part of my text (like 2 or 3 characters at the time) should appear in the EditText. Then when a user touches a key again, another 2 or 3 characters of the text should appear inside the EditText. I've thought a lot about it but I can't seem to find the right approach to do it. Where to store my Text and how to code so that the app overrides whatever the user inputs and adds 2 or 3 characters in the EditText according to my text that I need to store somewhere.
Any ideas?
Take a look at
http://developer.android.com/reference/android/text/TextWatcher.html
Implement a TextWatcher and check the user input in onTextChanged() to determine the user input. Mark the input the user has made with a Span (which can be any custom object, it is just used to tag the text area), so you can later look it up with Editable#getSpans() in afterTextChanged(), where you can replace the whole span with your override text.
Code idea (untested):
onTextChanged(CharSequence s, int start, int before, int count){
((Spannable)s).setSpan(new MyMarkObject(), start, start+count, Spannable.SPAN_MARK_MARK)
}
afterTextChanged(Editable s)
{
MyMarkObject[] markers = s.getSpans(0, s.length(), MyMarkObject.class);
for (MyMarkObject marker: markers){
int start = s.getSpanStart(marker);
int end = s.getSpanEnd(marker);
s.replace(start, end, getYourDesiredReplacementTextFor(s.subSequence(start,end));
}
}

add character after each word in edittext

i need to add a $ after each set of numbers a user enters in a edit text. For example as soon as a user enters a number the $ should be automatically placed in front of that number. I tried to use a textwatcher were i get the current string then add a $ and set the text of the edittext. When i do that the keyboard freezes.
It sounds like you have entered a infinite loop inside the onTextChanged method of your textwatcher. You need to remove the listener first, then make your changes, then re-add the listener:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Remove TextChangedlistener so that this function does not
// enter an infinite loop when we change it in code!
yourEditText.removeTextChangedListener(this);
// Add your code to insert the '$' symbol here
// Re-add listener
yourEditText.addTextChangedListener(this);
// This just moves the cursor back to the end of the input
yourEditText.setSelection(editText.getText().length());
}

How to clear 'text-watcher' previous value in android?

I am using onTextChanged(CharSequence s, int start, int before, int count) of Text watcher which is attached to MultiAutoCompleteTextView in my activity.
When I type some text for eg. 'nik' in MultiAutoCompleteTextView , then drop down list opens with some suggested sentences, when one item is selected from the drop down eg. (nikhil kaushik;) and then I do back press too delete a character, every thing gets deleted expect initial search value 'Nik'.
How to prevent this, I don't want every thing to get deleted, only last character should be deleted from 'nikhil kaushik;'.
Request you to please help me on this.
Set empty string "" in the text view at the end of your onTextChanged method or Override afterTextChanged method of text watcher and set text view with empty string.

EditText.setText() gives index out of bounds

I'm having an error I can't seem to wrap my head around. I'm writing an app that allows the user to send text from an EditText to a TextView. If the user makes a mistake, the user can hit the space key to bring the most recent text sent from the EditText to the TextView. This works sometimes, but other times, it gives me an IndexOutOfBounds exception.
textInput is an EditText, back1,2,3 are the three most recent strings (with back1 the most recent)
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(count==1&&before==0&&s.toString().equals(" ")){
textInput.setText(back1);
}else if(s.toString().equals(back1 + " ")){
textInput.setText(back2);
}else if(s.toString().equals(back2 + " ")){
textInput.setText(back3); //causes error if back2 > back3
}
textInput.setSelection(textInput.getText().toString().length());
The above code checks if the user hit the space key, and if so, what to do with it. If the user pressed space on an empty EditText, they get the last thing they sent. If they hit space again, they get the next to last thing they sent, and so on. This is still a bit rough, but I hope you get the idea.
The OutOfBounds exception comes from taking a large item in the EditText, hitting space, and setting the EditText to a smaller string. I assumed it was because the cursor is at the end of the EditText and could no longer be there when the text got smaller, so I tried adding textInput.setSelection(0) right before the setText(). That didn't help. I also tried setting the EditText to setText(""). That didn't work either. If I comment out the lines of setText(back#), everything works fine.
An example:
A user types in "hello", "hi" and "hey" in that order.
back3 = hello, back2 = hi, and back1 = hey.
Hitting space once will set the EditText to "hey"
A second tap will crash, since the setSpan(3...4) ends beyond length 2, presumably because back 1 is larger than back2. It is supposed to set the text in the EditText to "hi"
From the TextWatcher documentation:
public abstract void onTextChanged (CharSequence s, int start, int before, int count)
Since: API Level 1
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. It is an error to attempt to make changes to s from this callback.
(My emphasis.)
You should use afterTextChanged instead if you want to change the text more in response to an existing change. Even in this case, your handler will be called re-entrantly when you change the text from afterTextChanged, so use an extra precaution to make sure you won't get into an infinite loop, such as something like this:
public void afterTextChanged (Editable s) {
static boolean is_reentrant = false;
if (!is_reentrant) {
is_reentrant = true;
try {
// do stuff
} finally {
is_reentrant = false;
}
}
}
I haven't tested this exact snippet, but something like that will make your code only run if it's not already running. You don't need to worry about thread-safety in this case, because it's only being called from inside the same thread.

Android - TextWatcher is invoked once for each character in pasted text

I've added a TextWatcher to an EditText and am listening for changes in the text via the onTextChanged(CharSequence s, int start, int before, int count) method. When I paste text that has say 10 characters, into this EditText, onTextChanged() gets called 10 times, once for each character in the text I pasted, from left to right. I want onTextChanged() to be called only once after all 10 characters have been pasted into the EditText. I'm sure this should be possible, because otherwise what's the point in having the "count" param if it's always going to be 1?
count won't always be 1: for instance, if you select and delete a block of text or if you choose an autocomplete option.
In any case, the details of whether pasting happens in one chunk or one character at a time is an implementation detail, and if you rely on either behavior it's likely your app will break in the future.
Try using afterTextChanged it will only get one call

Categories

Resources