How to update the same EditText using TextWatcher? - java

In my Android application I need to implement a TextWatcher interface to implement onTextChanged. The problem I have is, I want to update the same EditText With some extra string. When I try to do this the program terminates.
final EditText ET = (EditText) findViewById(R.id.editText1);
ET.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
try
{
ET.setText("***"+ s.toString());
ET.setSelection(s.length());
}
catch(Exception e)
{
Log.v("State", e.getMessage());
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override
public void afterTextChanged(Editable s)
{
}
});
My program terminates and even I try to catch the exception like in my code still it terminates.
Does anyone have any idea why this happens and how I can achieve this? Thanks.

The content of the TextView is uneditable on the onTextChanged event.
Instead, you need to handle the afterTextChanged event to be able to make changes to the text.
For more thorough explanation see: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
Note: Error onTextChanged
Obvioulsy, you are causing an endless loop by continuously changing the text on afterTextChanged event.
From the ref:
public abstract void afterTextChanged (Editable s)
This method is called to notify you that, somewhere within s, the text has been
changed. It is legitimate to make further changes to s from this
callback, but be careful not to get yourself into an infinite loop,
because any changes you make will cause this method to be called again
recursively. ...
Suggestion 1: if you can, check if the s is already what you want when the event is triggered.
#Override
public void afterTextChanged(Editable s)
{
if( !s.equalsIngoreCase("smth defined previously"))
s = "smth defined previously";
}
Suggestion 2: if you need to do more complex stuff (formatting,
validation) you can maybe use a synchronized method like in this
post.
Note 2 : Formatting the input as partially hidden with n stars till the last 4 chars ( ****four)
You can use something like this in suggestion 1:
#Override
public void afterTextChanged(Editable s)
{
String sText = ET.getText().toString()
if( !isFormatted(sText))
s = format(sText);
}
bool isFormatted(String s)
{
//check if s is already formatted
}
string format(String s)
{
//format s & return
}

To supplement Zortkun's answer (where the example code is quite broken), this is how you'd use afterTextChanged() to update the same EditText:
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
if (!editable.toString().startsWith("***")) {
editable.insert(0, "***");
}
}
});
Get familiar with the Editable interface to learn about other operations besides insert().
Note that it's easy to end up in an infinite loop (the changes you do trigger afterTextChanged() again), so typically you'd do your changes inside an if condition, as above.
As afterTextChanged() javadocs say:
It is legitimate to make further changes to s from this callback, but
be careful not to get yourself into an infinite loop, because any
changes you make will cause this method to be called again
recursively.

late answer, if someone looking this is how i did it.
set addTextChangedListener initially
in one of the call back (say onTextChanged()) remove addTextChangedListener
Still interested in receiving updates add it back again.
here is the code.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.d("log", "before");
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("log", "after");
editText.removeTextChangedListener(this);
ediText.setText("text you wanted to put");
editText.addTextChangedListener(this);
}
#Override
public void afterTextChanged(Editable s) {
}
});

Here is a snippet that worked for me
etPhoneNumber.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().equals(Utils.getFormattedNumber(s.toString()))) {
s.replace(0, s.length(), Utils.getFormattedNumber(s.toString()));
}
}
});
where Utils.getFormattedPhoneNumber() is your method returning a formatted number

Related

how to use TextWatcher with query in android?

I have made an EditText where I type inside it some name.
I had like the app to perform search every time something changed in my EditText.
I used the following code:
txt_search.addTextChangedListener( new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
query = txt_search.getText().toString();
fetchBooks(query);
}
#Override
public void afterTextChanged(Editable s) {
query = txt_search.getText().toString();
fetchBooks(query);
}
} );
Where fetchBooks is the method that performs the search inside the API based on the query.
The problem im facing is that sometimes the search is stuck. If for example, I type pretty fast, it gives the results only for the first few letters and not for the whole query in the end.
Eventually, what I'm trying to get is that the app will constantly perform search based on the text inside the EditText.
Is there a way to obtain it without getting stuck results?
Thank you
First:
Remove search operation code for AfterChangedListener because after text is entered in EditText completely your search operation execute on both onTextChanged listener and afterTextChanged Listener
Second Replace txt_search.getText().toString(); with 's.toString()'
Change your TextWatcher as below
txt_search.addTextChangedListener( new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
query = s.toString();
fetchBooks(query);
}
#Override
public void afterTextChanged(Editable s) {
}
} );
For more information I recommend you to see below links:
getText vs onTextChanged charSequence
android Edittext with textwatcher

Updating Seekbar after changing Edittext

So I've got a seekbar and an edittext. My aim is to type in a number in the edittext, and in the same time the seekbar should jump to the related position. This should also work vise versa.
I've already got the code for them seperately. But something is missing. Because when I put in both and start then i can slide the seekbar and the value is changing in the same time in the edittext. But when i try to type in a number, it jumps to the beginning. Example: i want to type 123...result is 321. more or less the same with deleting.
I think the two codes are crashing each other, bit i don't know what to change.
And maybe i should say that i'm new in this field.
I'm not sure if my intentions are understandable..
Here my codes:
1.
value.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int after, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try{
//Update Seekbar value after entering a number
int progress = Math.round(Float.parseFloat(s.toString()));
seekbar.setProgress(progress);
value.setText(value.getText().length());
} catch(Exception ex) {}
}
});
2.
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
value.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
As you see, there is a parameter passed into "onProgressChanged" function called "fromUser":
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
It defines that progress is changed by "physically" shfting the slider, so all You have to do, is just type as below:
if (fromUser) value.setText(String.valueOf(progress));
It prevents doing this kind of loop.
value.setText(value.getText().length());
This line is called first, changing the text.
value.setText(String.valueOf(progress));
Then this line is called, changing the text to something else. These 2 setText()'s happen so fast, you cannot see that it happened twice, you only see the result of the last one.
I propose you remove the value.setText(value.getText().length());, displaying the length of the value string is not something you want to do, if I understand your question correctly.
The problem is in your afterTextChanged() method.
1. Remove line value.setText(value.getText().length()); from afterTextChanged().
value.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int after, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try {
int progress = Math.round(Float.parseFloat(s.toString()));
seekBar.setProgress(progress);
} catch (Exception e) {}
}
});
2. Update onProgressChanged() method as below, to move cursor position as per text change.
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
value.setText(String.valueOf(progress));
value.setSelection(String.valueOf(progress).length());
}
OUTPUT:
Hope this will help~
value.setText(value.getText().length()); is not using to display the length. It is used to place the cursor position at the end of edittext instead of going it to start position

Count characters with TextWatcher fails on HTC longpress

I have 3 EditText elements, and I want to jump from one field to the next if there are 4 characters in the input.
I use a TextWatcher for this:
getEditView(R.id.edit_code1).addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable input) {
if(input.length() == 4){
getEditView(R.id.edit_code2).requestFocus();
}
}
});
The inputType for the EditText is "textCapCharacters"
When doing a longpress on a key to get a number, like holding R to get a 4, most devices will not add the letter, until the user stops holding the button, and will fire afterTextChanged after the letter 4 is selected. On a HTC keyboard (In this case the HTC Desire on 2.3.5) this is not the case. Even though the user is still holding the button, the R is added to the EditText and afterTextChanged is fired, and the code does its job and puts the focus on the next field.
How can this undesired behavior be prevented? Watching onKeyDown/Up won't help, because it doesn't register normal keystrokes.
getEditView(R.id.edit_code1).addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
if(input.length() >3){
getEditView(R.id.edit_code2).requestFocus();
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable input) {
}
}
});
Unfortunately it's a bug in the HTC keyboard with no way of fixing it. This being an event in the IME, it is impossible intercept touch or key events, so you would probably be better off simply making the user skip to the next input instead of you doing it for them.
If it's that important for you though, you can implement your own kind of keyboard there, with only the keys you need.

Detect a new line in android text view

I am trying to create my first Android application in which it will help me do some outlining.
Quite simply I am trying to write some sort of detection that when a line starts with a hyphen, the next time there is a new line a hyphen will be placed in front of that new line.
I am looking for any pointers or directions for where I should be looking, as this is my first app.
Or in another sense what would be the best way to detect text being typed and change the EditText based on it.
Since OnKeyListener does not work for Soft keyboard, I recommend using the TextWatcher.
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if( -1 != charSequence.toString().indexOf("\n") ){
// Do your stuff
}
}
When you want to replace this sequence by some other string, try this:
public void afterTextChanged(Editable editable) {
int i = editable.toString().indexOf("\n");
if ( i != -1 ) {
editable.replace(i, i+1, "");
}
}
You could use the text watcher class of android which can be attached to a event.
EditText mPasswordLength = (EditText)findViewById(R.id.password_length);
mPasswordLength.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s){
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
public void onTextChanged(CharSequence s, int start, int before, int count){
}
});
The method you can use to edit the text is onTextChanged. More detailed description about when and why these events are fired is explained in this post.. Read the answer with max up votes.
You want an OnKeyListener for the EditText, then in the listener's onKey(View v, int keyCode, KeyEvent event) method, see if it is the event is KeyEvent.ACTION_DOWN and the keyCode is for KeyEvent.KEYCODE_ENTER, if so then append a '-' to the end of the edittext.

How to restrict Single Quote in android EditText?

friends,
i want to restrict " character in android EditText any one guide me how to achieve this in java code?
You probably want to set an InputFilter on your EditText object
This page has an example of an InputFilter for numeric values
((EditText)findViewById(R.id.EditText01)).addTextChangedListener(new TextWatcher()
{
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
//check here if character is '"' if yes don't allow to right
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
#Override
public void afterTextChanged(Editable s)
{
// TODO Auto-generated method stub
}
});
May this solve it?
How to restrict special characters from an Android EditText field?
use the onKeyDown or onTextChanged event

Categories

Resources