76

I have a ListActivity with my customized adapter and inside each of the view, it may have some buttons, in which I need to implement OnClickListener. I need to implement the OnClickListener in the adapter. However, I don't know how to call the function like startActivity() or setResult(). Since the adapter doesn't extend to Activity.

So what is the best way to solve this problem?

Thanks.

Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45
justicepenny
  • 2,004
  • 2
  • 24
  • 48

9 Answers9

204

Just pass in the current Context to the Adapter constructor and store it as a field. Then inside the onClick you can use that context to call startActivity().

pseudo-code

public class MyAdapter extends Adapter {
     private Context context;

     public MyAdapter(Context context) {
          this.context = context;     
     }

     public View getView(...){
         View v;
         v.setOnClickListener(new OnClickListener() {
             void onClick() {
                 context.startActivity(...);
             }
         });
     }
}
Robby Pond
  • 73,164
  • 16
  • 126
  • 119
  • but one more question, what if I need to call setResult? because i need to call onActivityResult(...) function in my activity. thanks for your help. – justicepenny Nov 16 '10 at 20:09
  • 1
    If you want to return some result from the child activity, you need to start the activity with startActivityForResult instead of StartActivity, and override onActivityResult (which is called after the child activity ends). – Robby Pond Nov 24 '10 at 17:56
  • 1
    @RobbyPond Context does not have startActivityForResult() ! http://developer.android.com/reference/android/content/Context.html – C-- Jul 12 '12 at 12:18
  • 3
    you can cast context like that: ((Activity) context).startActivityForResults(intent,0); – Xenione Jul 25 '12 at 11:08
  • Is there a way to putExtra and Finish() current activity? – harishannam Jul 15 '15 at 21:23
68

When implementing the onClickListener, you can use v.getContext.startActivity.

btn.setOnClickListener(new OnClickListener() {                  
    @Override
    public void onClick(View v) {
        v.getContext().startActivity(PUT_YOUR_INTENT_HERE);
    }
});
ccheneson
  • 49,072
  • 8
  • 63
  • 68
  • 1
    but one more question, what if I need to call setResult? because i need to call onActivityResult(...) function in my activity. thanks for your help. – justicepenny Nov 16 '10 at 20:10
32
public class MyAdapter extends Adapter {
     private Context context;      


     public MyAdapter(Context context) {
          this.context = context;         
     }


     public View getView(...){  
         View v;  
         v.setOnClickListener(new OnClickListener() {
             void onClick() {
                  Intent intent= new Intent(context, ToActivity.class); 
                   intent.putExtra("your_extra","your_class_value");
                 context.startActivity(intent);
             }
         });
     }
}
amin saffar
  • 1,953
  • 3
  • 22
  • 34
edwin
  • 7,985
  • 10
  • 51
  • 82
  • 1
    An old thread but adding for newer search results: this callback from adapter goes anti design pattern as Intents should be created and executed within activities listeners are best for this used case. – DevKRos Jan 20 '17 at 11:23
14

For newer versions of sdk you have to set flag activity task.

public void onClick(View v)
 {
     Intent myactivity = new Intent(context.getApplicationContext(), OtherActivity.class);
     myactivity.addFlags(FLAG_ACTIVITY_NEW_TASK);
     context.getApplicationContext().startActivity(myactivity);
 }
Kamran
  • 2,711
  • 2
  • 17
  • 24
  • 1
    This is the real answer due to: context.getApplicationContext().startActivity(myactivity); If you use alone context.startActivity(intent) it won't work! Just solve the issue this way for kotlin on android – Ramiro G.M. Dec 19 '19 at 02:46
4

Simple way to start activity in Adopter's button onClickListener:

Intent myIntent = new Intent(view.getContext(),Event_Member_list.class);                    myIntent.putExtra("intVariableName", eventsList.get(position).getEvent_id());
                view.getContext().startActivity(myIntent);
sanyassh
  • 8,100
  • 13
  • 36
  • 70
2

callback from adapter to activity can be done using registering listener in form of interface: Make an interface:

      public MyInterface{
         public void  yourmethod(//incase needs parameters );
         }

In Adapter Let's Say MyAdapter:

    public MyAdapter extends BaseAdapter{
       private MyInterface listener;

    MyAdapter(Context context){
        try {
            this. listener = (( MyInterface ) context);
              } catch (ClassCastException e) {
               throw new ClassCastException("Activity must implement MyInterface");
          }

//do this where u need to fire listener l

          try {
                listener . yourmethod ();
            } catch (ClassCastException exception) {
               // do something
            }

      In Activity Implement your method:


         MyActivity extends AppCompatActivity implements MyInterface{

                yourmethod(){
                //do whatever you want
                     }
                     }
DevKRos
  • 422
  • 2
  • 15
2
view.getContext().startActivity(intent);

view - public void onClick(View view) OnClick of image.

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
Ravi Kumar
  • 21
  • 1
1

First Solution:

You can call start activity inside your adapter like this:

public class YourAdapter extends Adapter {
     private Context context;

     public YourAdapter(Context context) {
          this.context = context;     
     }

     public View getView(...){
         View v;
         v.setOnClickListener(new OnClickListener() {
             void onClick() {
                 context.startActivity(...);
             }
         });
     }
}

Second Solution:

You can call onClickListener of your button out of the YourAdapter class. Follow these steps:

Craete an interface like this:

public YourInterface{
         public void  yourMethod(args...);
}

Then inside your adapter:

    public YourAdapter extends BaseAdapter{
               private YourInterface listener;

           public YourAdapter (Context context, YourInterface listener){
                    this.listener = listener;
                    this.context = context;
           }

           public View getView(...){
                View v;
         v.setOnClickListener(new OnClickListener() {
             void onClick() {
                 listener.yourMethod(args);
             }
         });
}

And where you initiate yourAdapter will be like this:

YourAdapter adapter = new YourAdapter(getContext(), (args) -> {
            startActivity(...);
        });

This link can be useful for you.

Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45
0

If you want to redirect on url instead of activity from your adapter class then pass context of with startactivity.

btnInstall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(link));
                intent.setData(Uri.parse(link));
                context.startActivity(intent);
            }
        });