如何删除使用 addTextChangedListener 添加的所有侦听器
我有一个 ListView,其中每一行都有一个 EditText 控件。我想向每一行添加一个 TextChangedListener
;一个包含额外数据的数据,表明 EditText
位于哪一行。问题是,当调用 getView
时,会添加多个 TextWatchers
;因为 convertView
已经有一个 TextWatcher
(并且指向另一行)。
MyTextWatcher watcher = new MyTextWatcher(currentQuestion);
EditText text = (EditText)convertView.findViewById(R.id.responseText);
text.addTextChangedListener(watcher);
MyTextWatcher
是我实现 TextWatcher
的类;并处理文本事件。 CurrentQuestion 让我知道我正在对哪一行进行操作。当我在框中输入时;调用 TextWatcher
的多个实例。
在添加新的之前,有什么方法可以删除 TextWatchers
吗?我看到了 removeTextChangedListener
方法,但这需要传入特定的 TextWatcher
,而且我不知道如何获取指向 TextWatcher
的指针code> 已经存在了。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
无法直接使用当前的
EditText
界面来执行此操作。我看到两种可能的解决方案:TextWatcher
添加到特定的EditText
实例中。EditText
并添加清除所有观察者的可能性。以下是第二种方法的示例 -
ExtendedEditText
:以下是如何在 xml 布局中使用
ExtendedEditText
:There is no way to do this using current
EditText
interface directly. I see two possible solutions:TextWatcher
are added to particularEditText
instance.EditText
and add possibility to clear all watchers.Here is an example of second approach -
ExtendedEditText
:And here is how you can use
ExtendedEditText
in xml layouts:您可以从 EditText 中删除 TextWatcher。首先,我建议您将 TextWatcher 声明移到 editText.addTextChangedListener(...) 之外:
之后您将能够设置 TextWather 更简单一些:
比您可以像这样删除 TextWatcher :
并根据需要设置另一个。
You can remove TextWatcher from your EditText. First of all I suggest you to move TextWatcher declaration outside the the editText.addTextChangedListener(...):
After that you will be able to set TextWather little bit simpler:
Than you can remove TextWatcher like this:
and set another if you want.
我还花了很多时间寻找解决方案,最终在如下标签的帮助下解决了问题。
它将通过从 ConvertView 的标签获取引用来删除以前的 TextWatcher 实例。
它完美地解决了这个问题。
在您的 CustomAdapter 文件中,设置一个新的内部类,如下所示:
然后在您重写的 public View getView(intposition, View ConvertView, ViewGroupparent) 方法中实现如下逻辑:
然后实现 TextWatcher 类,如下所示:
它将删除以前的 TextWatcher 实例通过从 ConvertView 的标签获取引用
I also spent a lot of time finding the solution and finally ended up solving with the help of tag like below.
It would remove previous TextWatcher instances by getting references from tag of the convertView.
It perfectly solves the problem.
In your CustomAdapter file, set a new inner class like below:
Then in your overrided public View getView(int position, View convertView, ViewGroup parent) method implement the logic like below:
Then implement TextWatcher class as below:
It would remove previous TextWatcher instances by getting references from tag of the convertView
这个问题已经问了很久了,但有人可能会发现这很有用。 Recyclerview 中 TextWatcher 的问题是我们必须确保在视图回收之前将其删除。否则,我们会丢失 TextWatcher 的实例,并且在 OnBindViewHolder() 中调用removeTextChangedListener(textWatcher)只会删除 TextWatcher 的当前实例。
我解决这个问题的方法是在 FocusChangedListener 中添加 TextChangedListener :
这样我确信当 editText 没有焦点时,文本观察器将被删除,并在获得焦点时再次添加。因此,当 recyclerview 被回收时,editText 将删除所有 textChangeListener。
It has been long since this question was asked, but someone might find this useful. The problem with TextWatcher in Recyclerview is that we have to make sure it is removed before the view is recycled. Otherwise, we loss the instance of the TextWatcher, and calling removeTextChangedListener(textWatcher) in the OnBindViewHolder() will only remove the current instance of TextWatcher.
The way I solve this problem is to add the TextChangedListener inside a FocusChangedListener:
This way I am sure when the editText doesn't have focus then the textwatcher is removed, and added again when it has focus. So, when the recyclerview is recycled the editText will have any textChangeListener removed.
我在 RecyclerView 中的许多 EditText 中遇到了类似的问题。我通过反思解决了它。在绑定视图之前调用
ReflectionTextWatcher.removeAll(your_edittext)
。这段代码找到所有 TextWatchers 并将它们从本地 EditText 的名为“mListeners”的列表中删除。我希望,这会对某人有所帮助。
I struggled with a similar problem with a lot of EditTexts in RecyclerView. I solved it by reflection. Call
ReflectionTextWatcher.removeAll(your_edittext)
before bind views. This piece of code finds all TextWatchers and removes them from the local EditText's list called "mListeners".I hope, this will help someone.
将当前文本观察器保存在视图保持器中,您可以找到要删除的文本观察器。
Save the current textwatcher in viewholder and you can find the one you want to remove.
如果像我一样处理
ViewHolder
,那么在创建文本观察器时简单地保存对它的引用是没有帮助的。重用后,视图将到达其他一些ViewHolder
,它不会引用旧的文本观察器,因此无法删除它。就我个人而言,我选择解决像 @inazaruk 这样的问题,尽管将代码更新为 Kotlin + 重命名类以更好地反映其目的。
If one, like me, deals with
ViewHolder
, then simply saving a reference to a text watcher upon its creation will not help. Upon reuse the view will get to some otherViewHolder
which would not have a reference to that old text watcher, thus one won't be able to delete it.Personally i chose to solve problem like @inazaruk, though updated code to Kotlin + renamed class to better reflect it's purpose.
正如您在这里看到的: TextView的CodeSearch没有办法删除所有侦听器。唯一的方法是提供您用来注册它的观察者。
我还不完全明白为什么还有其他听众已经注册。但是,您可以子类化 EditText,重写 addTextChangedListener(..) 并在其中自己保留所有添加的引用的副本,然后委托给超类实现。然后,您还可以提供一个附加方法来删除所有侦听器。
如果您需要进一步的解释,请联系我们。
As you can see here: CodeSearch of TextView there is no way of removing all listeners. The only way is to provide the watcher you used to register it.
I do not yet fully understand why there are other listeners already registered. However you can subclass the EditText, override the addTextChangedListener(..) and in it keep a copy of all added references yourself and then delegate to the superclass implementation. You then can also provide an additional method that removes all listeners.
Get in touch if you need further explanations.
我在 xamarin/C# 中遇到了同样的问题,我为此编写了一个类来管理 ListView 内的单击事件,其中项目视图将被“回收”:
您可以在 ListView BaseAdapter GetItem 方法中以这种方式使用它:
ViewOnClickEventHandler 类将关心你的文本视图上的多个事件。您还可以更改 textchange 事件的类。原理是一样的。
我希望这会有所帮助。
再见,
NXEXO007
I had the same problem with xamarin/C# and I wrote for this a class to manage click events inside a ListView where the item view will be "recycled":
You can use it in your ListView BaseAdapter GetItem method this way:
The ViewOnClickEventHandler class will care about multiple events on your textview. You can also change the class for textchange events. It's the same princip.
I hope this will help.
bye,
nxexo007
我解决了这种情况,没有扩展 TextView 类。
I resolved this situation without extend TextView class.
我也遇到过类似的问题。我通过在 ArrayList 中保存对 textWatchers 的引用来解决这个问题:
I struggled with a similar problem. I solved it by saving references to my textWatchers in an
ArrayList
:我在
RecyclerView
项中的ViewHolder
中使用EditText
时遇到了问题,并且当ViewHolder
已绑定,导致调用了先前绑定调用中添加的TextWatcher
,因此,永无休止的循环。唯一可行的解决方案是存储
TextWatcher
> 在列表中,然后在onBindViewHolder
,遍历该列表并从EditText
中删除TextWatcher
。在将
TextWatcher
分配给EditText
之前将其添加到列表:绑定项目时删除它们,将遍历整个
textWatcherList
:没有任何除了传递
TextWatcher
对象之外,还有一种从EditText
中删除TextWatcher
的方法,因此它需要存储在我们计划删除的某个地方稍后再说。I've run into the issue when using
EditText
inViewHolder
inRecyclerView
item, and it was causing error of infinite loop, whenViewHolder
was binding, cause theTextWatcher
added in previous bind call was called, hence, never-ending loop..The only working solution for that was to store
TextWatcher
's in the list, and then inonBindViewHolder
, go trough that list and removeTextWatcher
from theEditText
.Add
TextWatcher
to list before assigning it toEditText
:Remove them when binding the item, going to trough the entire
textWatcherList
:There isn't any other way to remove the
TextWatcher
's fromEditText
, than passing theTextWatcher
object, hence it needs to be stored somewhere is we plan to remove it later.我删除文本观察者所做的事情非常简单。我创建了一个数组来放置我的文本观察器:
我将它们添加到:
我的 returnTextWatcherCheckPIN 方法在 afterTextChanged 上使用不同的检查器( switchMethod 来检查所有四个 editTexts)实例化一个文本观察器。
然后,每当我删除文本观察器时,我只是引用数组中的文本观察器:
在调试时检查 editText 的侦听器大小:
已删除!这解决了我的问题!
What I did to remove text watchers is very simple. I created an array to put my textwatchers:
I added them in:
My returnTextWatcherCheckPIN method instantiates a textWatcher with a different checker (switchMethod to check all four editTexts) on afterTextChanged.
Then whenever I remove a text watcher I just referenced the one from the array:
Check the listeners size of the editText on debug:
It's removed! That solved my problem!
为什么不使用
setTag()
将TextWatcher
引用附加到EditText
本身?在
/values
包下的ids.xml
中:Why not attach the
TextWatcher
reference to theEditText
itself withsetTag()
?In
ids.xml
under/values
package:因为我是使用 notifiDataSetChange 时在适配器中面临 EditText doOnTextChanged 侦听器多个侦听器问题的人之一。经过大量研究和尝试多种方法后,我在@Davi 给出的答案部分找到了解决方案。
现在,我在 @Davi 先生的回答之上制作了一个 Kotlin 内联 函数,以便更轻松地使用。希望它会对你们有所帮助
这是您的使用方法
最后在通知更改适配器之前您必须明确焦点
As I'm one of those who face EditText doOnTextChanged listener multiple listener problems in the adapter when using notifiDataSetChange. After so much research and trying lots of ways, I found a solution here in the answer section given by @Davi.
And now I made an Kotlin inline function for more easy way to use, this on top of Mr @Davi s answer. Hope it will help you guys
Here's how you use
And finally you must clear focus before notifi change adapter