6563cc10d2
6563cc10d2

Reputation: 193

Updating a part of the RecyclerView

i have a recycle view that contains a description of a comment and a vote count when i press up i need the count to increase this is how it looks like at the moment enter image description here

but the problem is when i press up the vote does increase but until i close that fragment and reopen it it does not update

what actually happens is when i press up vote it makes an API call which does some logic and sends it over to android which has a number of the vote for that particular item which was being clicked or upvoted

how can i update that particular record so that i can see the change without reopening the view

code: CommentItem.java



public CommentItem(String id, String description, String voteCount)
{ 
        this.id = id;
        this.description= description;
        this.voteCount = voteCount;
}
//getters and setters

CommentItemAdapter.java

...
private OnItemClickListener mlistener;
/*Interfaces*/
public  interface  OnItemClickListener{
    void VoteUpClick(int position);
    void VoteDownClick(int position);
...
}
...

CommentFragment.java

 @Override
public void VoteUpClick(final int position) { 
  final CommentItem clickeedItem = 
 mitemList.get(position);
    StringRequest strReq = new StringRequest(Request.Method.POST,
                                        AppConfig.URL, new Response.Listener<String>() {
                 @Override
       public void onResponse(String response) {
              try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");
                    if (!error) {
                                 String errorMsg = jObj.getString("msg");
                                Toast.makeText(getContext(), errorMsg, 
                                Toast.LENGTH_SHORT).show();                                              
                    } else {
                            String msg= jObj.getString("msg");
                            Toast.makeText(getContext(), msg, 
                            Toast.LENGTH_SHORT).show();
                            }
                } catch (JSONException e) {
                       e.printStackTrace();
                       }
                 }
           }, new Response.ErrorListener() {
                 @Override
       public void onErrorResponse(VolleyError error) {}
        }) {
               @Override
             protected Map<String, String> getParams() {
             Map<String, String> params = new HashMap<String, String>();

                 params.put("voteType", "up");
                 params.put("commentID", clickeedItem.getId().toString());
                                        return params;
                                    }
                                };
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}

Upvotes: 4

Views: 203

Answers (2)

Yurii Tsap
Yurii Tsap

Reputation: 3744

A lot of people here had a nice advice to use DiffUtils. Thats quite a reasonable way to handle diffs inside dataset of RecycleView.

The best way to perform it right now is to use ListAdapter, which requires a DiffUtil.ItemCallback or AsyncDifferConfig. A really big pros of ListAdapter is that all differ logic is done on background, which in turns optimizes your UI. Everything you need is to override this funs: areItemsTheSame() and areContentsTheSame(), additionally u have getChangePayload() - for detailed info about the changed item. Don't use the notifyDataSetChanged() and other range update functions, all of that stuff is handled under-the-hood.

Yours case could be handled via different approaches. I prefer having an intermediate state which will notify user that something happens. So you can locally mark that comment with pending vote up, for example yellow arrow and when response is obtained from back-end you just need to refresh the data-list and the ItemCallback will do the diff trick for you. When response is retrieved and vote is applied it can be marked as green arrow. Those are just thoughts about the right flow.

In any case everything you need is to use the ListAdapter.sumbitList(newDataSet) and the internal differ of ListAdapter will use ItemCallback to compare old and new list.

Upvotes: 1

Azamat Mahkamov
Azamat Mahkamov

Reputation: 1090

If I get it right, simply adapter.notifyDataSetChanged() will update your list. But There is a better way, using DiffUtils in recyclerView. That is, comparing old and new list, and updating only the changed item, not changing the whole data set.

Have a look at it out

https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00

Other approach, is to have the viewHolder reference from the Activity/Or Fragment, when onItemClick happens, by recyclerView.findViewHolderForAdapterPosition(position). Then change view by this view

Upvotes: 3

Related Questions