简体   繁体   English

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

[英]Why is the RecyclerView adapter not updating correctly (only the first time) despite getting the correct data?

This is very strange. 这很奇怪。 For some reason, despite getting the correct data from the REST call, the adapter is not updated correctly in the RecyclerView. 由于某些原因,尽管从REST调用中获取了正确的数据,但适配器在RecyclerView中没有正确更新。

Here are the two methods: 这是两种方法:

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);
}

Here are the logs. 这是日志。 Let me first clarify that the first half is correct. 首先让我澄清一下,上半部分是正确的。 First line, "in request" user id is ABC and the first number 2 represents topics.size() and the "new instance" number 2 represents itemCount (also topics.size() in the adapter) after the adapter has been initiated. 第一行,“请求中”用户ID是ABC,并且启动适配器后,第一个数字2表示topic.size(),“新实例”数字2表示itemCount(在适配器中也是topic.size())。 The topic size of 2 is what it supposed to be for user ABC. 主题大小2应该是用户ABC的大小。

I sign out user ABC and sign in a different user with id DEF. 我注销用户ABC并使用ID DEF登录另一个用户。 So naturally, it also first logs "in request" with the new user id. 因此,自然也首先使用新的用户ID登录“请求”。 Good. 好。 "inside" is also logging correctly. “内部”也正确记录。 The topics.size() of 1 is logging correctly. topic.size()为1正确记录。

Now here comes the strange part. 现在来了奇怪的部分。 "new instance", which is again the itemCount for the topics.size() in the adapter after it had been initiated, somehow is equal to 2, not 1. As you can see, the log with "new instance" comes after adapter has been initiated to getInstance(topics), a new adapter instance with topics set changed. “新实例”,它也是启动后适配器中topic.size()的itemCount,以某种方式等于2,而不是1。如您所见,带有“新实例”的日志位于适配器之后已启动到getInstance(topics),这是一个更改了主题集的新适配器实例。

Also weird, after I close the app, and open the app again, the data for user DEF seem to go back to normal. 同样奇怪的是,在我关闭应用程序并再次打开应用程序之后,用户DEF的数据似乎恢复了正常。

Also, as a note, all this is happening in a fragment, not an activity 另外,请注意,所有这些都是在片段中发生的,而不是活动

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

The getInstance(topics) code is as follows: 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();
}
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;
}

This code is incorrect. 该代码不正确。 Look at it and think about what happens when instance is not null. 查看它,并考虑实例不为null时会发生什么。

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

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

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

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