У меня есть действие Лента сообщений (что-то вроде ленты новостей Facebook), и в его макете есть EditText , Кнопка Поделиться вверху и RecyclerView под ним. RecyclerView показывает сообщения всех пользователей, получая все сообщения с сервера и привязывая данные через адаптер в методе OnCreate.

Когда Пользователь публикует что-то, набирая текст в EditText и нажимая кнопку «Поделиться», данные отправляются на сервер (я использую Retrofit), и после успешного ответа от сервера я вызываю ту же функцию, которая вызывает метод OnCreate для отображения все сообщения для обновления RecyclerView.

Проблема, с которой я столкнулся, заключается в том, что данные отправляются на сервер, но макет обновляется только тогда, когда я нажимаю кнопку «Назад», чтобы скрыть / закрыть клавиатуру после набора текста или Показать / открыть клавиатуру, нажав EditText.

Ниже приведены некоторые из кодов для лучшего понимания:

Здесь я отправляю запрос на сервер, когда пользователь что-то публикует:

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 здесь и здесь но это не решило мою проблему

3
Usman Anwar 24 Сен 2018 в 20:59

2 ответа

Лучший ответ

Я решил указанную выше проблему с помощью ответа Арсалана Хана.

Фактически 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 для всех значений, я изменю его позже, прямо сейчас я сосредоточусь на Основные функции.

1
Usman Anwar 26 Сен 2018 в 04:37

Здесь следует вызвать init RecyclerView:

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();
    }
0
Erselan Khan 25 Сен 2018 в 19:35