8

我正在使用RecyclerViewgreenrobot eventbusSyncAdapter完成同步后, 我将一条消息发布到消息总线中:SyncAdapter

EventBus.getDefault().post(new EventMessagesRefreshed());

在我的目标类中,我执行以下操作:

@Subscribe
public void onEvent(EventMessagesRefreshed event) {
    this.init();
}

在我的init()我为recyclerview创建适配器并设置它:

public void init() {
    if(this.listRowParent != null) {
        this.adapter = new FragmentMessagesListAdapter(this.getActivity(), SingletonMessages.getInstance().getMessages());
        this.listRowParent.setAdapter(this.adapter);
    }
}

// listRowParent is my RecyclerView!

接收事件的片段位于选项卡视图的内部。所以有多个选项卡,有时当我不在正确的目标选项卡中时,有时当然会将SyncAdapter帖子发布到消息总线中,但由于它已注册,它会尝试调用并创建适配器并将其设置为. 如果发生这种情况,我会收到以下错误:EventMessagesRefreshedinit()RecyclerView

Could not dispatch event: class EventMessagesRefreshed to subscribing class class FragmentMessagesList
java.lang.IllegalStateException: Observer android.support.v7.widget.RecyclerView$RecyclerViewDataObserver@2c3421a7 was not registered.
    at android.database.Observable.unregisterObserver(Observable.java:69)
    at android.support.v7.widget.RecyclerView$Adapter.unregisterAdapterDataObserver(RecyclerView.java:5688)
    at android.support.v7.widget.RecyclerView.setAdapterInternal(RecyclerView.java:873)
    at android.support.v7.widget.RecyclerView.setAdapter(RecyclerView.java:857)

所以我需要init()我的适配器,并且RecyclerView只有在RecyclerViewDataObserver注册时。

我怎样才能做到这一点?

4

1 回答 1

8

您需要注册数据观察者来监听来自同步适配器的数据变化。

mRecyclerViewAdapter.registerAdapterDataObserver(myObserver);

RecyclerView.AdapterDataObserver 是您调用通知方法的结果。因此,例如,如果您在将项目添加到适配器后调用 notifyItemInserted(),则将调用 onItemRangeInserted()

一个更详细的例子

protected void setupRecyclerView() {
    mAdapter = new MyAdapter(mItemList);
    mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            checkAdapterIsEmpty();
        }
    });

    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setHasFixedSize(true);

    mRecyclerView.setAdapter(mAdapter);
    checkAdapterIsEmpty();
}`

适配器可以发布描述特定更改的各种事件。并非所有适配器都支持所有更改类型,如果没有更具体的数据,有些适配器可能会退回到通用的“某些更改”事件。

于 2016-03-14T20:31:54.943 回答