尽管获得了正确的数据,为什么RecyclerView适配器无法正确更新(仅第一次)?

时间:2018-01-23 08:26:48

标签: java android listview android-fragments android-recyclerview

这很奇怪。出于某种原因,尽管从REST调用中获取了正确的数据,但在RecyclerView中未正确更新适配器。

以下是两种方法:

public Observable<Response<GetTopicsByCreatorResponseBody>> getTopicsByCreator(GetTopicsByCreatorRequest request) {
    return getApi()
            .getTopics(request)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

public void getTopicsByCreator(GetTopicsByCreatorRequest request) {
    mBinding.swipeRefreshContainer.setRefreshing(true);
    Log.d(TAG, "getTopicsByCreator: in request" + request.getUserId());
    Disposable disposable = mViewModel.getTopicsByCreator(request)
            .subscribe((Response<GetTopicsByCreatorResponseBody> response) -> {
                if (response.body() != null) {
                    GetTopicsByCreatorResponseBody body = response.body();
                    if (body.getTopics() != null) {
                        Log.d(TAG, "getTopicsByCreator: inside" + body.getTopics().get(0).getCreator().getUserId());
                        List<Topic> topics = body.getTopics();
                        Log.d(TAG, "getTopicsByCreator: " + topics.size());
                        RecyclerView.Adapter adapter = mBinding.recyclerForumTopicsForUser.getAdapter();
                        if (adapter instanceof GetTopicsByCreatorAdapter) {
                            ((GetTopicsByCreatorAdapter) adapter).setTopics(topics);
                            Log.d(TAG, "getTopicsByCreator: instanceof" + ((GetTopicsByCreatorAdapter) adapter).getItemCount());
                        } else {
                            adapter = GetTopicsByCreatorAdapter.getInstance(topics);
                            Log.d(TAG, "getTopicsByCreator: new instance" + ((GetTopicsByCreatorAdapter) adapter).getItemCount());
                            mBinding.recyclerForumTopicsForUser.setAdapter(adapter);
                        }
                    }
                }
            }, (Throwable ex) -> {
                Log.e(TAG, "getTopicsByCreator: " + ex.getClass().getSimpleName() + ": " + ex.getMessage());
            });
    mViewModel.addDisposable(disposable);
    mBinding.swipeRefreshContainer.setRefreshing(false);
}

以下是日志。首先让我澄清一下,上半年是正确的。第一行,&#34;请求&#34;用户ID是ABC,第一个数字2代表topics.size()和&#34;新实例&#34;在启动适配器后,数字2表示itemCount(适配器中的topics.size())。主题大小为2应该是用户ABC的原因。

我注销用户ABC并使用ID为DEF登录其他用户。很自然,它也首先在请求中记录&#34;&#34;使用新用户ID。好。 &#34;内部&#34;也正确记录。 topic.size()为1正确记录。

现在出现了奇怪的部分。 &#34;新实例&#34;,在启动后适配器中的topics.size()又是itemCount,不知何故等于2,而不是1.正如您所看到的,带有&的日志34;新实例&#34;在将适配器启动到getInstance(主题)之后,一个主题设置已更改的新适配器实例。

同样奇怪,在关闭应用程序并再次打开应用程序后,用户DEF的数据似乎恢复正常。

另外,作为一个注释,所有这一切都发生在片段中的,而不是活动

D/GetTopicsByCreatorFragment: getTopicsByCreator: in requestABC
D/GetTopicsByCreatorFragment: getTopicsByCreator: insideABC
D/GetTopicsByCreatorFragment: getTopicsByCreator: 2
D/GetTopicsByCreatorFragment: getTopicsByCreator: new instance2
D/GetTopicsByCreatorFragment: getTopicsByCreator: in requestDEF
D/GetTopicsByCreatorFragment: getTopicsByCreator: insideDEF
D/GetTopicsByCreatorFragment: getTopicsByCreator: 1
D/GetTopicsByCreatorFragment: getTopicsByCreator: new instance2

getInstance(topics)代码如下:

public static GetForumTopicsByCreatorAdapter getInstance(List<Topic> topics) {
    if (sInstance == null) {
        synchronized (GetForumTopicsByCreatorAdapter.class) {
            if (sInstance == null) {
                sInstance = new GetForumTopicsByCreatorAdapter(topics);
                sInstance.notifyDataSetChanged();
            } else {
                sInstance.setTopics(topics);
            }
        }
    }
    return sInstance;
}

public void setTopics(List<Topic> topics) {
    mTopics = topics;
    notifyDataSetChanged();
}

1 个答案:

答案 0 :(得分:0)

public static GetForumTopicsByCreatorAdapter getInstance(List<Topic> topics) {

   // two checks for null 
    if (sInstance == null) { //one here
        synchronized (GetForumTopicsByCreatorAdapter.class) {
            if (sInstance == null) {  //and one here
                sInstance = new GetForumTopicsByCreatorAdapter(topics);
                sInstance.notifyDataSetChanged();
            }  else  {
                sInstance.setTopics(topics);
            }
        }
    }
    /// at this point, if instance was not null, nothing is done on it and is returned as is.
     /// So new items are not added.
    return sInstance;
}

此代码不正确。看看它并考虑当实例不为空时会发生什么。

public static GetForumTopicsByCreatorAdapter getInstance(List<Topic> topics) {

    // this is what heppens when instance is not null. topics variable is not used
    return sInstance;
}