在软键盘 Open/Close 之前,RecyclerView 不会更新

RecyclerView doesn't Update until Soft Keyboard is Open/Close

我有一个 Posts Feed(类似于 Facebook News Feed)Activity 在它的布局中我有一个 EditText ,在顶部分享Button,在其下方分享一个RecyclerView。 RecyclerView通过OnCreate方法中的Adapter从Server获取所有Post并绑定数据,显示所有用户的Post。

当用户 post 通过在 EditText 中输入一些文本并点击共享按钮时,数据被发送到服务器(我正在使用 Retrofit)并且在服务器成功响应后我调用相同的函数调用在 OnCreate 方法中显示所有 Post 以更新 RecyclerView。

我面临的问题是数据已 post 发送到服务器,但仅当我在输入后按 Hide/Close 键盘的后退按钮或 Show/Open 通过点击 EditText 进入键盘。

为了更好的理解,下面是一些代码:

这里我向服务器发送请求时用户Post something:

Call<CreatePost> call = mAPIService.sharePost(apiKey, post_description);
        call.enqueue(new Callback<CreatePost>() {
            @Override
            public void onResponse(@NonNull Call<CreatePost> call, @NonNull Response<CreatePost> response) {
                boolean error = response.body().getError();
                if (!error) {
                    displayFeedPosts();
                }
            }

            @Override
            public void onFailure(@NonNull Call<CreatePost> call, @NonNull Throwable t) {
                Log.d(TAG, "Error: " + t.getMessage());
            }
        });

这是 displayFeedPosts 方法:

private void displayFeedPosts() {
        Call<FeedPosts> call = mAPIService.displayFeedPosts(apiKey);
        call.enqueue(new Callback<FeedPosts>() {
            @Override
            public void onResponse(@NonNull Call<FeedPosts> call, @NonNull Response<FeedPosts> response) {
                boolean error = response.body().getError();
                if (!error) {
                    ArrayList<Post> feedPosts = response.body().getPosts();
                    for (Post post : feedPosts) {
                        mTripFeedPostUserNames.add(post.getFirstName() + " " + post.getLastName());
                        mTripFeedPostTime.add(post.getPostDatetime());
                        mTripFeedPostContent.add(post.getPostDescription());
                    }
                }
            }

            @Override
            public void onFailure(@NonNull Call<FeedPosts> call, @NonNull Throwable t) {
                Log.d(TAG, "Error: " + t.getMessage());
            }
        });

        initRecyclerView();
    }

    private void initRecyclerView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true);
        RecyclerView recyclerView = findViewById(R.id.trip_feed_recycler_view);
        recyclerView.setNestedScrollingEnabled(false);
        recyclerView.setLayoutManager(layoutManager);
        mTripFeedPostRecyclerViewAdapter = new TripFeedPostRecyclerViewAdapter(this, mTripFeedPostProfileImages, mTripFeedPostUserNames, mTripFeedPostTime, mTripFeedPostContent, mTripFeedPostImages, mTripFeedPostID);
        recyclerView.setAdapter(mTripFeedPostRecyclerViewAdapter);
    }

PS:我是Android的新手,如果我做错了事情,我深表歉意。欢迎您提出建议。

注意:关于 ListView here and here 也有人问过同样的问题,但它没有解决我的问题

应该在这里调用 initRecyclerView:

private void displayFeedPosts() {
        Call<FeedPosts> call = mAPIService.displayFeedPosts(apiKey);
        call.enqueue(new Callback<FeedPosts>() {
            @Override
            public void onResponse(@NonNull Call<FeedPosts> call, @NonNull Response<FeedPosts> response) {
                boolean error = response.body().getError();
                if (!error) {
                    ArrayList<Post> feedPosts = response.body().getPosts();
                    for (Post post : feedPosts) {
                        mTripFeedPostUserNames.add(post.getFirstName() + " " + post.getLastName());
                        mTripFeedPostTime.add(post.getPostDatetime());
                        mTripFeedPostContent.add(post.getPostDescription());
                    }
               initRecyclerView();
                }
            }

            @Override
            public void onFailure(@NonNull Call<FeedPosts> call, @NonNull Throwable t) {
                Log.d(TAG, "Error: " + t.getMessage());
            }
        });
    }

private void initRecyclerView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true);
        RecyclerView recyclerView = findViewById(R.id.trip_feed_recycler_view);
        recyclerView.setNestedScrollingEnabled(false);
        recyclerView.setLayoutManager(layoutManager);
        mTripFeedPostRecyclerViewAdapter = new TripFeedPostRecyclerViewAdapter(this, mTripFeedPostProfileImages, mTripFeedPostUserNames, mTripFeedPostTime, mTripFeedPostContent, mTripFeedPostImages, mTripFeedPostID);
        recyclerView.setAdapter(mTripFeedPostRecyclerViewAdapter);
        mTripFeedPostRecyclerViewAdapter.notifyDataSetChanged();
    }

我在答案的帮助下解决了上述问题。

实际上 initRecyclerView() 并未在 onResponse() 方法之外执行。将它包含在 onResponse() 方法中并使用 notifyDataSetChanged() 而不是 initRecyclerView() 解决了问题。

数据被填充两次的解决方法我通过如下方式修改displayFeedPosts()解决了:

private void updateFeedPosts() {
        Call<FeedPosts> call = mAPIService.displayFeedPosts(apiKey);
        call.enqueue(new Callback<FeedPosts>() {
            @Override
            public void onResponse(@NonNull Call<FeedPosts> call, @NonNull Response<FeedPosts> response) {
                boolean error = response.body().getError();
                if (!error) {
                    mTripFeedPostProfileImages.clear();
                    mTripFeedPostUserNames.clear();
                    mTripFeedPostTime.clear();
                    mTripFeedPostContent.clear();
                    mTripFeedPostImages.clear();
                    mTripFeedPostID.clear();
                    mTripFeedPostRecyclerViewAdapter.notifyDataSetChanged();
                    ArrayList<Post> feedPosts = response.body().getPosts();
                    for (Post post : feedPosts) {
                        mTripFeedPostProfileImages.add(post.getProfilePicture());
                        mTripFeedPostUserNames.add(post.getFirstName() + " " + post.getLastName());
                        mTripFeedPostTime.add(post.getPostDatetime());
                        mTripFeedPostContent.add(post.getPostDescription());
                        mTripFeedPostImages.add(post.getPostImagePath());
                        mTripFeedPostID.add(post.getPostTripfeedId());
                    }
                    mTripFeedPostRecyclerViewAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onFailure(@NonNull Call<FeedPosts> call, @NonNull Throwable t) {
                Log.d(TAG, "Error: " + t.getMessage());
            }
        });
    }

我清除了适配器数据,然后用更新的数据再次填充它。 希望我的回答对遇到同样问题的人有所帮助。

PS: 我知道我没有以正确的方式使用我的适配器模型,我只能对所有值使用一个 ArrayList,我稍后会修改它,现在我专注于主要功能。