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:
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?Code: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 } } };
Here's what I'm copying-and-pasting all over the place currently:
Where the KEY_*'s are different for each version.Code: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) { } });
One idea I had was something like this:
... 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.Code:TextWatcher tw = new TextWatcher() { public int mKey; public void afterTextChanged(Editable s) { handleTextUpdate(mKey, true); } // ...and of course the other required methods };
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?
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):
Code: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); }
Bookmarks