繁体   English   中英

检测到适配器上的项目视图已被破坏

[英]Detect item view on Adapter has been destroyed

我有一个带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被回收时似乎被调用了。

谢谢!

根据这个官方问题onViewDetachFromWindow BUT存在问题

在这种情况下,不一定会调用onDetachedFromWindow()。 ListView子项被回收和重用,ListView尽可能避免使用不必要的onDetachedFromWindow()。
但是,当销毁Activity或从窗口分离ListView时,应为适配器创建的所有视图调用onDetachedFromWindow()。

所以你不能指望列表视图被销毁。

您的项目视图必须扩展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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM