如何再次调用notifyDatasetChanged()来停止getView调用?
我的问题:
我有一个文本字段,用于过滤textchange上的适配器。如果我经常更改文本,我会得到ArrayIndexOutOfBoundsException,因为当seconding过滤操作已经在运行时,getView当然仍然在访问适配器列表。
所以ATM就是这样的:
编辑:
如果我看到过滤器线程处于活动状态,我想立即从getview返回?
编辑:
确定相关的适配器代码:
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filterLock.acquireUninterruptibly();
FilterResults r = new FilterResults();
List<T> items = null;
m_Filter = constraint;
if (constraint == null /* TextUtils.isEmpty(constraint) */) { // AR
// auskommentiert
// da
// ungewünscht
items = m_AllItems;
} else {
items = m_FilteredItems;
items.clear();
synchronized (SyncLock) {
for (T item : m_AllItems) {
if (DynamicArrayAdapter.this.filter(item, constraint)) {
items.add(item);
}
}
}
}
r.values = items;
r.count = items.size();
return r;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
m_Items = (List<T>) results.values;
notifyDataSetChanged();
filterLock.release();
}
这是从Filter扩展的过滤器。 m_Items和m_AllItems用在适配器中(第一个包含过滤的,第二个包含未过滤的)。正如您所看到的那样,它们未在performFiltering()中进行修改。此外,filterLock是1号信号量,因此不会同时进行2次过滤操作。
EDIT2:
另外,在我的onTextChanged中,我可以向你保证我不会以任何方式修改那里的适配器,我也不会在performFiltering()调用的filter()方法中
答案 0 :(得分:0)
更改为适配器而非UI线程是导致问题的原因。 如果你将所有的适配器修改发布到UI线程,它将不会发生,因为它一个接一个地发生。
您可以在不同的线程中执行繁重的处理,但是当您想要将更改放入适配器时,您需要使用处理程序或Activity.runOnUiThread
在UI线程上执行此操作。例如:
// Really heavy filtering process
runOnUiThread(new Runnable(){
public void run(){
// Change items of Adapter here
// Now we are notifying that the data has changed.
mAdapter.notifyDataSetChanged();
}
});
看到你的代码后:
正如Luksprog所说,你不应该直接从其他线程更改列表,而是使用列表的副本。
会发生什么是ListView接受大小为X的列表,但您已将其更改为Y的大小,并且ListView不知道它。
您需要在项目列表的副本上完成工作,完成后,在UI线程中发布Runnable
更改适配器中的项目列表并调用notifyDataSetChanged()
,这就是您不会与你的ListView和你的适配器发生冲突。