覆盖notifyDataSetChanged()方法

4

我有一个自定义的ArrayAdapter。当数据在ListView中显示时,我总是希望它被排序,因此我尝试重写notifyDataSetChanged()方法来先对适配器进行排序,像这样:

@Override
public void notifyDataSetChanged() {
    sort(new Comparator<IceContact>() {
        @Override
        public int compare(IceContact iceContact, IceContact iceContact2) {
            return iceContact.compareTo(iceContact2);
        }
    });
    super.notifyDataSetChanged();
}

IceContact类是一个实现Comparable接口的get-set类。不幸的是,这给我带来了一个讽刺的StackOverflowError(如下面logcat所示)。然后我尝试反过来做。覆盖sort()并在此之后直接调用notifyDataSetChanged(),代码如下:

@Override
public void sort(Comparator<? super IceContact> comparator) {
    super.sort(comparator);
    notifyDataSetChanged();
}

这很好!有人能解释一下吗?感觉它们的实现方式基本相同。


01-21 18:25:50.725: ERROR/AndroidRuntime(2490): FATAL EXCEPTION: main
    java.lang.StackOverflowError
    at android.view.View.setFocusableInTouchMode(View.java:5584)
    at android.widget.AdapterView.checkFocus(AdapterView.java:717)
    at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:812)
    at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6044)
    at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
    at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
    at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:70)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(IceContactAdapter.java:71)
    at android.widget.ArrayAdapter.sort(ArrayAdapter.java:278)
    at se.naxiait.curbits.utils.IceContactAdapter.notifyDataSetChanged(Ic

注册一个 DataSetObserver 来进行排序。 - njzk2
@njzk2 谢谢!但我打算创建一个名为 sort() 的新函数(没有参数),这样每次想要对数据进行排序时就不必传递比较器了。 - Niklas Ekman
3个回答

5
IceContact是一个实现了Comparable的get-set类。然而,这给我带来了一个讽刺的问题,即StackOverflowError(下面是日志)。sort()默认调用notifyDataSetChanged(),然后再次调用sort(),接着又会调用notifyDataSetChanged(),然后再调用sort(),如此往复......。
在notifyDataSetChanged()中,对数据进行排序时,不要同时调用notifyDataSetChanged(),因为sort()会自动处理它。
在第二种情况下,你基本上需要调用两次notifyDataSetChanged():先调用super.sort(),将数据排序并调用notifyDataSetChanged();然后再由您来调用一个notifyDataSetChanged()。

谢谢!这让我疯了!只要我被允许(还有几分钟),我就会接受这个答案。 - Niklas Ekman
@njzk2,我所指的“super”调用是指super.sort(),它将对数据进行排序并调用notifyDataSetChanged()(在super.sort()之后还有额外的notifyDataSetChanged)。 - user
1
没错,我的错,我读得太快了。在第二种情况下确实调用了两次notifyDataSetChanged。 - njzk2

0

您可以使用registerAdapterDataObserver

 adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            //your code;
        }
    });

-1
一个简单的方法来防止异常就是禁用调用notifyDataSetChanged()。
@Override
public void notifyDataSetChanged() 
{
    setNotifyOnChange(false);
    sort(yourComparatorInstance);
    super.notifyDataSetChanged();
}

根据文档,它将自动重新启用:

...并且调用notifyDataSetChanged()会将标志重置为true。

这就是sort()所做的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接