Call Activity method from adapter

Solution 1:

Yes you can.

In the adapter Add a new Field :

private Context mContext;

In the adapter Constructor add the following code :

public AdapterName(......, Context context) {
  //your code.
  this.mContext = context;
}

In the getView(...) of Adapter:

Button btn = (Button) convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {
  @Override
  public void onClick(View v) {
    if (mContext instanceof YourActivityName) {
      ((YourActivityName)mContext).yourDesiredMethod();
    }
  }
});

replace with your own class names where you see your code, your activity etc.

If you need to use this same adapter for more than one activity then :

Create an Interface

public interface IMethodCaller {
    void yourDesiredMethod();
}

Implement this interface in activities you require to have this method calling functionality.

Then in Adapter getView(), call like:

Button btn = (Button) convertView.findViewById(yourButtonId);
btn.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mContext instanceof IMethodCaller) {
            ((IMethodCaller) mContext).yourDesiredMethod();
        }
    }
});

You are done. If you need to use this adapter for activities which does not require this calling mechanism, the code will not execute (If check fails).

Solution 2:

You can do it this way:

Declare interface:

public interface MyInterface{
    public void foo();
}

Let your Activity imlement it:

    public class MyActivity extends Activity implements MyInterface{
        public void foo(){
            //do stuff
        }
        
        public onCreate(){
            //your code
            MyAdapter adapter = new MyAdapter(this); //this will work as your 
                                                     //MyInterface listener
        }
    }

Then pass your activity to ListAdater:

public MyAdapter extends BaseAdater{
    private MyInterface listener;

    public MyAdapter(MyInterface listener){
        this.listener = listener;
    }
}

And somewhere in adapter, when you need to call that Activity method:

listener.foo();

Solution 3:

Original:

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 an Activity.

In your Activity:

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.

public class MyActivity extends Activity implements AdapterCallback {

    private MyAdapter myAdapter;

    @Override
    public void onMethodCallback() {
       // do something
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myAdapter = new MyAdapter(this);
    }
}

In your Adapter:

In the Activity, 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 adapterCallback;

    public MyAdapter(Context context) {
        try {
            adapterCallback = ((AdapterCallback) context);
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement AdapterCallback.", e);
        }
    }

    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int position) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    adapterCallback.onMethodCallback();
                } catch (ClassCastException e) {
                   // do something
                }
            }
        });
    }

    public static interface AdapterCallback {
        void onMethodCallback();
    }
}

Solution 4:

Basic and simple.

In your adapter simply use this.

((YourParentClass) context).functionToRun();

Solution 5:

For Kotlin:

In your adapter, simply call

(context as Your_Activity_Name).yourMethod()