Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create interface between Fragment and adapter?

I have fragment with ListView, say MyListFragment, and custom CursorAdapter. I'm setting onClickListener in this adapter for the button in the list row.

public class MyListAdapter extends CursorAdapter {      public interface AdapterInterface {         public void buttonPressed();     }      ...      @Override     public void bindView(final View view, final Context context, final Cursor cursor) {         ViewHolder holder = (ViewHolder) view.getTag();          ...          holder.button.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View v) {                 // some action                 // need to notify MyListFragment             }         });     } }  public MyListFragment extends Fragment implements AdapterInterface {      @Override     public void buttonPressed() {         // some action     } } 

I need to notify fragment when the button is pressed. How to invoke this interface?

Help, please.

like image 707
Sabre Avatar asked Mar 16 '13 00:03

Sabre


2 Answers

Make a new constructor and an instance variable:

AdapterInterface buttonListener;  public MyListAdapter (Context context, Cursor c, int flags, AdapterInterface buttonListener) {   super(context,c,flags);   this.buttonListener = buttonListener; } 

When the Adapter is made, the instance variable will be given the proper reference to hold.

To call the Fragment from the click:

public void onClick(View v) {    buttonListener.buttonPressed(); } 

When making the Adapter, you will have to also pass your Fragment off to the Adapter. For example

MyListAdapter adapter = new MyListAdapter (getActivity(), myCursor, myFlags, this); 

since this will refer to your Fragment, which is now an AdapterInterface.

Keep in mind that on orientation of the Fragment changes, it will most likely be recreated. If your Adapter isn't recreated, it can potentially keep a reference to a nonexistent object, causing errors.

like image 198
A--C Avatar answered Sep 22 '22 09:09

A--C


Using Eventbus:

Examples:

https://github.com/kaushikgopal/RxJava-Android-Samples/tree/master/app/src/main/java/com/morihacky/android/rxjava/rxbus

or

https://github.com/greenrobot/EventBus

Using Interfaces:

I understand the current answer but needed a more clear example. Here is an example of what I used with an Adapter(RecyclerView.Adapter) and a Fragment.

Create Callback Interface:

public interface AdapterCallback {     void onMethodCallback(); } 

Passing in Callback/Fragment:

This will implement the interface that we have in our Adapter. In this example, it will be called when the user clicks on an item in the RecyclerView.

In your Fragment:

public class MyFragment extends Fragment implements AdapterCallback {      private MyAdapter mMyAdapter;      @Override     public void onMethodCallback() {        // do something     }      @Override     public void onCreate(final Bundle savedInstanceState) {         super.onCreate(savedInstanceState);          this.mMyAdapter = new MyAdapter(this); // this class implements callback     } } 

Use the Callback in your Adapter:

In the Fragment, we initiated our Adapter and passed this as an argument to the constructer. This will initiate our interface for our callback method. You can see that we use our callback method for user clicks.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {      private AdapterCallback mAdapterCallback;      public MyAdapter(AdapterCallback callback) {         this.mAdapterCallback = callback;     }      @Override     public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {         // simple example, call interface here         // not complete         viewHolder.itemView.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View v) {                 mAdapterCallback.onMethodCallback();             }         });     } } 

or Use the Fragment in your Adapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {      private AdapterCallback mAdapterCallback;      public MyAdapter(Fragment fragment) {         try {             this.mAdapterCallback = ((AdapterCallback) fragment);         } catch (ClassCastException e) {             throw new ClassCastException("Fragment must implement AdapterCallback.");         }     }      @Override     public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {         // simple example, call interface here         // not complete         viewHolder.itemView.setOnClickListener(new OnClickListener() {             @Override             public void onClick(View v) {                 try {                     mAdapterCallback.onMethodCallback();                 } catch (ClassCastException exception) {                    // do something                 }             }         });     } } 
like image 27
Jared Burrows Avatar answered Sep 22 '22 09:09

Jared Burrows