我有一个带BaseAdapter的ListView。我想经常更新列表中的一些项目而不刷新内容。为了实现这一点,我正在使用Observer模式。我有一个Observable对象,列表中的每个项目都是观察者。
public View getView(final int position, View convertView, final ViewGroup parent) {
final ItemViewHolder holder;
final Item item = (Item) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent, false);
/* ADD VIEWS TO HOLDER */
holder = new ItemViewHolder();
convertView.setTag(holder);
ItemObserver observer = new ItemObserver(holder, context);
mapObservers.put(holder, observer);
observable.addObserver(observer);
} else {
holder = (ItemViewHolder) convertView.getTag();
}
//Set values into view etc...
return convertView;
}
这很有效,但问题是:我怎么知道不再需要观察者?我想检测给定视图何时被销毁,以便从Map获取观察者并从Observable对象中删除它。在视图被销毁时是否有任何侦听器?
我尝试了AbsListView.RecyclerListener.onMovedToScrapHeap(View view)
但似乎在回收View时调用了它。
谢谢!
答案 0 :(得分:4)
根据this offical issue,onViewDetachFromWindow
但
onDetachedFromWindow()不一定会在此调用 情况。列表显示 孩子们被回收和重复使用,ListView避免了不必要的 尽可能使用onDetachedFromWindow() 但是,onDetachedFromWindow() 应该在销毁Activity时调用适配器创建的所有视图 当ListView与窗口分离时。
所以你不能指望列表视图被销毁。
答案 1 :(得分:2)
您的项目视图必须扩展android视图并覆盖下一个方法:
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// View is now detached, and about to be destroyed.
// Remove observer here.
}
阅读完评论后,我决定解释一下列表视图的工作原理。
最大的问题是适配器正在重用视图。向下滚动列表时,最重要的项目视图将被重复使用(不会被销毁!)以显示最低的项目视图。如果覆盖适配器的getView()方法,则会在下一个方法中反映出来:
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
...
return view;
}
它背后的作用:
if (convertView == null) {
view = mInflater.inflate(resource, parent, false);
} else {
view = convertView;
}
因此,convertView永远不会被破坏,但重用。回到问题,您应该根据变量位置更新持有者值,在行之后:
holder = (ItemViewHolder) convertView.getTag();
// Update your holder/observer here. Something like:
holder.setPosition(position);