View Full Version : Making a generic TextWatcher for multiple EditTexts
divestoclimb
03-19-2009, 01:29 PM
I thought I'd throw this out here to see if anyone has ideas... I'm at my wits end.
I'm writing an app with a lot of parallel-structured widgets within a single Activity that lets the user select the same type of information, but with different meanings. I've figured out how to simplify setting up all the listeners for the buttons and such by creating HashMaps and referencing widgets by keys that are binary OR'ed together, it's actually pretty slick. For the example with buttons, the listeners do something like this:
Button.OnClickListener l = new Button.OnClickListener() {
private void onClick(View v) {
int this_buttons_keys = mButtonIdKeyHash.get(v.getId());
if((this_buttons_keys & KEY_PLUSBUTTON) > 0) {
// This button is used for adding
}
if((this_buttons_keys & KEY_MINUSBUTTON) > 0) {
// This button is used for subtracting
}
}
};
The problem is I can't do this with a TextWatcher on an EditText because the TextWatcher methods don't get passed the View that called them. Is there any way to set parameters within a TextWatcher dynamically so I don't have to rewrite the same TextWatcher in the code for every EditText with a single line changed?
ruivieira
03-20-2009, 07:29 AM
I thought I'd throw this out here to see if anyone has ideas... I'm at my wits end.
I'm writing an app with a lot of parallel-structured widgets within a single Activity that lets the user select the same type of information, but with different meanings. I've figured out how to simplify setting up all the listeners for the buttons and such by creating HashMaps and referencing widgets by keys that are binary OR'ed together, it's actually pretty slick. For the example with buttons, the listeners do something like this:
Button.OnClickListener l = new Button.OnClickListener() {
private void onClick(View v) {
int this_buttons_keys = mButtonIdKeyHash.get(v.getId());
if((this_buttons_keys & KEY_PLUSBUTTON) > 0) {
// This button is used for adding
}
if((this_buttons_keys & KEY_MINUSBUTTON) > 0) {
// This button is used for subtracting
}
}
};
The problem is I can't do this with a TextWatcher on an EditText because the TextWatcher methods don't get passed the View that called them. Is there any way to set parameters within a TextWatcher dynamically so I don't have to rewrite the same TextWatcher in the code for every EditText with a single line changed?
Sorry, I'm not really sure what you want to do, but can't you just subclass TextWatcher so it can hold the EditText that called it and process the text accordingly?
Can you give a generic example of what you're trying to achieve?
divestoclimb
03-21-2009, 08:50 PM
Here's what I'm copying-and-pasting all over the place currently:
mEditTextArray.get(KEY_ONE | KEY_TWO | KEY_THREE).addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
handleTextUpdate(KEY_ONE | KEY_TWO | KEY_THREE, true);
}
// We don't use these methods
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) { }
});
Where the KEY_*'s are different for each version.
One idea I had was something like this:
TextWatcher tw = new TextWatcher() {
public int mKey;
public void afterTextChanged(Editable s) {
handleTextUpdate(mKey, true);
}
// ...and of course the other required methods
};
... then iterate through my HashMap and set tw.mKey each time before adding the listener to the EditText object. The problem is this doesn't work because TextWatcher is an interface, not a class, so my variables are automatically declared final.
I need a way to extend TextWatcher I guess? If I do that and make a custom class, won't I have a type incompatibility when I try to add the TextWatcher as a listener to an EditText?
divestoclimb
03-23-2009, 03:52 PM
Okay, I got it to work. I couldn't extend TextWatcher, but I was able to implement it in a subclass, something like this (from memory, I can share the real code on request):
private class MyTextWatcher implements TextWatcher {
private int mKey;
public MyTextWatcher(int key) {
mKey=key;
}
public void afterTextChanged(Editable s) {
handleTextUpdate(mKey, true);
}
// other methods are created, but empty
}
// ...
for (key ... ) {
MyTextWatcher tw = new MyTextWatcher(key);
mEditTextArray.get(key).addTextChangedListener(tw) ;
}
ruivieira
03-24-2009, 06:20 PM
Okay, I got it to work. I couldn't extend TextWatcher, but I was able to implement it in a subclass, something like this (from memory, I can share the real code on request):
private class MyTextWatcher implements TextWatcher {
private int mKey;
public MyTextWatcher(int key) {
mKey=key;
}
public void afterTextChanged(Editable s) {
handleTextUpdate(mKey, true);
}
// other methods are created, but empty
}
// ...
for (key ... ) {
MyTextWatcher tw = new MyTextWatcher(key);
mEditTextArray.get(key).addTextChangedListener(tw) ;
}
Cool.
I didn't realise that TextWatcher an interface... :o
If that's the case, then it's just as you did: just implement it in a class of your own.
Powered by vBulletin® Version 4.1.7 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.