I have a ListView
where each row has an EditText
control. I want to add a TextChangedListener
to each row; one that contains extra data which says which row the EditText
was in. The problem is that as getView
gets called, multiple TextWatchers
are added; because the convertView
already having a TextWatcher
(and one that points to a different row).
MyTextWatcher watcher = new MyTextWatcher(currentQuestion);
EditText text = (EditText)convertView.findViewById(R.id.responseText);
text.addTextChangedListener(watcher);
MyTextWatcher
is my class that implements TextWatcher
; and handles the text events. CurrentQuestion lets me know which row I'm acting upon. When I type in the box; multiple instances of TextWatcher
are called.
Is there any way to remove the TextWatchers
before adding the new one? I see the removeTextChangedListener
method, but that requires a specific TextWatcher
to be passed in, and I don't know how to get the pointer to the TextWatcher
that is already there.
There is no way to do this using current EditText
interface directly. I see two possible solutions:
TextWatcher
are added to particular EditText
instance.EditText
and add possibility to clear all watchers.Here is an example of second approach - ExtendedEditText
:
public class ExtendedEditText extends EditText
{
private ArrayList<TextWatcher> mListeners = null;
public ExtendedEditText(Context ctx)
{
super(ctx);
}
public ExtendedEditText(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
}
public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle)
{
super(ctx, attrs, defStyle);
}
@Override
public void addTextChangedListener(TextWatcher watcher)
{
if (mListeners == null)
{
mListeners = new ArrayList<TextWatcher>();
}
mListeners.add(watcher);
super.addTextChangedListener(watcher);
}
@Override
public void removeTextChangedListener(TextWatcher watcher)
{
if (mListeners != null)
{
int i = mListeners.indexOf(watcher);
if (i >= 0)
{
mListeners.remove(i);
}
}
super.removeTextChangedListener(watcher);
}
public void clearTextChangedListeners()
{
if(mListeners != null)
{
for(TextWatcher watcher : mListeners)
{
super.removeTextChangedListener(watcher);
}
mListeners.clear();
mListeners = null;
}
}
}
And here is how you can use ExtendedEditText
in xml layouts:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ua.inazaruk.HelloWorld.ExtendedEditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="header"
android:gravity="center" />
</LinearLayout>