Обновление RecyclerView при добавлении комментария - PullRequest
2 голосов
/ 19 апреля 2020

Я делаю CommentFragment. У меня есть RecyclerView для отображения комментариев и Edittext для написания комментариев. Однако, когда я добавляю комментарий, он отправляется на сервер, но RecyclerView не обновляется. Я использую notifydatasetchanged для обновления. Код:

 private void getComments(){

    Call<List<CommentsModel>> call=restApiClass.getComments(post_id);
    call.enqueue(new Callback<List<CommentsModel>>() {
        @Override
        public void onResponse(Call<List<CommentsModel>> call, Response<List<CommentsModel>> response) {

            if(response.isSuccessful()){

                list=response.body();
                if(commentsAdapter==null) {
                    commentsAdapter = new CommentsAdapter(list, getContext());
                }
                else{
                    commentsAdapter.notifyDataSetChanged();
                }
                recyclerView.setAdapter(commentsAdapter);
            }

        }
        @Override
        public void onFailure(Call<List<CommentsModel>> call, Throwable t) {
        }
    });
}

Я вызываю этот метод, когда нажимаю sendCommentTextView:

  sendCommentTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

              //............send comment codes.........
               getComments();

        }
    });

Ответы [ 2 ]

2 голосов
/ 19 апреля 2020

проверьте правильный ответ: пример notifyDataSetChanged .

Я думаю, что вы должны следовать этому ответу, чтобы адаптер работал, как и ожидалось, с notifyDataSetChanged (). Коротко: вам нужно обновить список внутри адаптера, а затем уведомить его об обновлении списка, чтобы он снова отображался в пользовательском интерфейсе (recyclerview).

PS: после функции notifyDataSetChanged вы не необходимо заново установить адаптер в окне программы-ресайклера, если он уже назначен.

1 голос
/ 19 апреля 2020

Здесь вы обновили list, когда Retrofit возвращает новые данные, но на самом деле вы не передавали свой адаптер этим данным; Вы только что вызвали commentsAdapter.notifyDataSetChanged();, но вам нужно сначала добавить метод, подобный updateList(List<CommentsModel> list), в свой адаптер и вызвать его с updateList(list); перед использованием commentsAdapter.notifyDataSetChanged();

Итак, добавьте updateList(List<CommentsModel> list) в свой адаптер обновить свой список внутренне, как показано ниже:

class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder> {
    ...

    List<CommentsModel> mList;

    updateList(List<CommentsModel> list) {
        this.mList.clear();
        this.mList.addAll(list);
    }

}

И тогда изменение в вашем коде может быть примерно таким:

call.enqueue(new Callback<List<CommentsModel>>() {
    @Override
    public void onResponse(Call<List<CommentsModel>> call, Response<List<CommentsModel>> response) {

        if(response.isSuccessful()){

            list=response.body();
            if(commentsAdapter==null) {
                commentsAdapter = new CommentsAdapter(list, getContext());
            }
            else{
                commentsAdapter.updateList(list);
                commentsAdapter.notifyDataSetChanged();
            }
            recyclerView.setAdapter(commentsAdapter);
        }

    }
    @Override
    public void onFailure(Call<List<CommentsModel>> call, Throwable t) {
    }
});

Обновление

Да, это работает, но recylerview возвращается на первую позицию и перезагружает список. Но я хочу загрузить только последний комментарий. Другие комментарии должны оставаться такими же. Так как я могу это сделать?

Чтобы просто обновить последний комментарий в вашем списке, затем добавьте новый метод в свой адаптер, который принимает только этот комментарий, и добавьте его в список, например:

class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder> {
    ...

    List<CommentsModel> mList;

    addComment(CommentsModel comment) {
        this.mList.add(comment);
        notifyItemInserted(mList.size()-1);
    }

}

Затем, когда данные возвращаются на Retrofit:

call.enqueue(new Callback<List<CommentsModel>>() {
    @Override
    public void onResponse(Call<List<CommentsModel>> call, Response<List<CommentsModel>> response) {

        if(response.isSuccessful()){

            list = response.body();
            if(commentsAdapter == null) {
                commentsAdapter = new CommentsAdapter(list, getContext());
            }
            else{
                // updating the adapter list with the last comment 
                commentsAdapter.addComment((CommentsModel) list.get(list.size()-1));

            }
            recyclerView.setAdapter(commentsAdapter);
        }

    }
    @Override
    public void onFailure(Call<List<CommentsModel>> call, Throwable t) {
    }
});
...