2

I have a Recycler View in which single row contains several views, including video, like statistic, and a button.

The button is to increment the value of like statistic to that item and update my adapter using notifyItemChange for that position.

My Problem is, while that row gets refreshed and updates my statistic, the video will reset and I will have to load the data from the beginning again.

What I want is like Facebook app, where user add emotion for a single row item, but the View (the video) does not get refreshed, and only certain items are refreshed, like the emotion statistics.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Karate_Dog
  • 1,265
  • 5
  • 20
  • 37

2 Answers2

4

You should consider using

void notifyItemChanged (int position,Object payload)

and capture the payload in

void onBindViewHolder (VH holder,int position, List<Object> payloads)

Based on the payloads parsed in, you can refresh part of your view in the ViewHolder

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
    if(payloads == null || payloads.isEmpty()) {
        onBindViewHolder(holder, position);//your normal method
    }
    else {
        //partial refresh
    }
}
WenChao
  • 3,586
  • 6
  • 32
  • 46
  • I used notifyItemChange(position, "payload data"), disabled item animator for my recycler view, but the onBindViewholder method with payload still does not get called, it only called onBindViewHolder without the payload. Is there something I'm missing? – Karate_Dog Feb 09 '17 at 06:55
  • When did you call `notifyItemChange`? It won't work if you use it right after `setAdapter` – WenChao Feb 09 '17 at 08:42
  • @Karate_Dog you can wrap the call to `recyclerview.post()` if you want to use it after `setAdapter` – WenChao Feb 09 '17 at 08:45
  • I called the `notifyItemChanged` right after I do the button press inside my View holder, but I call it inside the adapter class. Something like `void updateView(int position) { this.notifyItemChanged(position, new Object()) }` – Karate_Dog Feb 10 '17 at 07:09
3

You have to make use of payloads. This means, when notifying the adapter about dataset changes, you also are passing payloads, and this payload is being passed to appropriate callback within adapter, where you decide what view's need to be invalidated.

adapter.notifyItemChanged(position, payload); // payload is an Object

And you'll receive this payload in onBindViewHolder of adapter:

public void onBindViewHolder(HelloViewHolder holder, int position, List<Object> payload) {
        // decide what to update based on the payload
}

You can view this as an example.

Community
  • 1
  • 1
azizbekian
  • 60,783
  • 13
  • 169
  • 249