Best way to notify RecyclerView Adapter from Viewholder?
Asked Answered
A

1

7

I have a RecyclerView with multiple item view types so they are broken into separate ViewHolder classes. Before, when all the ViewHolders were in the same class as the RecyclerView Adapter, I could update the adapter directly when an item was clicked or deleted. However, I separated the ViewHolders into different classes to better organize the code. Now, I cannot directly update my RecyclerView Adapter. Which of the following solutions is the best way to communicate from my ViewHolder to my Adapter? If there is a better solution than the ones I have listed, please suggest!

  1. Using a Interface with a Callback listener. Keep in mind that there might be 5 - 10 different view types so would this method require 5 - 10 interfaces?
    1. Use an Eventbus library such as Greenrobot's Eventbus.

Is an interface or eventbus solution really the best way? There surely has to be a better method for communication between views and adapters!

Angelika answered 16/4, 2017 at 4:28 Comment(1)
You could also use data binding.Exoteric
I
10

I usually save reference to the adapter in activity or fragment. ViewHolders can be placed as inner classes in Adapter or as classes in separate package. You can use one interface to interact with view holders. You just need to implement it in your activity or fragment. For Example:

public class MyAdapter extends RecyclerView.Adapter<VH> {
    private MyInterface mInterface;

    public MyAdapter(MyInterface i) {
         mInterface = i;
    }

    //... some code to create view holders


    //binding
    @Override
    protected void onBindItemViewHolder(ViewHolder viewHolder, final int position, int type) {
        viewHolder.bindView(position, mInterface); //call methods of interface in bindView() methods of your viewHolders
    }

    interface MyInterface {
        void someEvent();
    }
}

public class ViewHolder extends RecyclerView.ViewHolder {

    TextView mText;

    ViewHolder(View root) {
        super(root);
        mText = (TextView)root.findViewById(R.id.text)
    }

    void bindView(int pos, MyAdapter.MyInterface myInterface) {
        mText.setOnClickListener(v -> myInterface.someEvent());
        //...some other code
    }
}

And somewhere in your activity or fragment:

final MyAdapter adapter = new MyAdapter(new MyAdapter.MyInterface() {
    @Override
    public void someEvent() {
        adapter.notifyDataSetChanged();
    }
});
Insolate answered 16/4, 2017 at 7:5 Comment(3)
Thanks for the suggestion and providing code bits to go along! I am going to try this later and see if I can get it to work with multiple viewholders and events without being too cumbersome. I will post back and let you know how it goes!Angelika
This method works great for interactions between Adapters and Viewholders. For interactions between Viewholders and the RecyclerView, EventBus is a better option.Angelika
@Ray Li Why would you ever need to communicate between ViewHolder and RecyclerView? The RecyclerView is just a ViewGroup that shows the data from it's Adapter. I don't remember to have used the RecyclerView for anything else than to place the container of a list.Stope

© 2022 - 2024 — McMap. All rights reserved.