Android - setOnClickListener vs OnClickListener vs View.OnClickListener

Imagine that we have 3 buttons for example

public class MainActivity extends ActionBarActivity {

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

        setContentView(R.layout.activity_main);


        // Capture our button from layout
        Button button = (Button)findViewById(R.id.corky);
        Button button2 = (Button)findViewById(R.id.corky2);
        Button button3 = (Button)findViewById(R.id.corky3);
        // Register the onClick listener with the implementation above
        button.setOnClickListener(mCorkyListener);
        button2.setOnClickListener(mCorkyListener);
        button3.setOnClickListener(mCorkyListener);

    }

    // Create an anonymous implementation of OnClickListener
    private View.OnClickListener mCorkyListener = new View.OnClickListener() {
        public void onClick(View v) {
            // do something when the button is clicked 
            // Yes we will handle click here but which button clicked??? We don't know

        }
    };

}

So what we will do?

public class MainActivity extends ActionBarActivity {

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

        setContentView(R.layout.activity_main);


        // Capture our button from layout
        Button button = (Button)findViewById(R.id.corky);
        Button button2 = (Button)findViewById(R.id.corky2);
        Button button3 = (Button)findViewById(R.id.corky3);
        // Register the onClick listener with the implementation above
        button.setOnClickListener(mCorkyListener);
        button2.setOnClickListener(mCorkyListener);
        button3.setOnClickListener(mCorkyListener);

    }

    // Create an anonymous implementation of OnClickListener
    private View.OnClickListener mCorkyListener = new View.OnClickListener() {
        public void onClick(View v) {
            // do something when the button is clicked
            // Yes we will handle click here but which button clicked??? We don't know

            // So we will make
            switch (v.getId() /*to get clicked view id**/) {
                case R.id.corky:

                    // do something when the corky is clicked

                    break;
                case R.id.corky2:

                    // do something when the corky2 is clicked

                    break;
                case R.id.corky3:

                    // do something when the corky3 is clicked

                    break;
                default:
                    break;
            }
        }
    };

}

Or we can do this:

public class MainActivity extends ActionBarActivity {

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

        setContentView(R.layout.activity_main);


        // Capture our button from layout
        Button button = (Button)findViewById(R.id.corky);
        Button button2 = (Button)findViewById(R.id.corky2);
        Button button3 = (Button)findViewById(R.id.corky3);
        // Register the onClick listener with the implementation above
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // do something when the corky is clicked
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // do something when the corky2 is clicked
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // do something when the corky3 is clicked
            }
        });

    }

}

Or we can implement View.OnClickListener and i think it's the best way:

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

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

        setContentView(R.layout.activity_main);


        // Capture our button from layout
        Button button = (Button)findViewById(R.id.corky);
        Button button2 = (Button)findViewById(R.id.corky2);
        Button button3 = (Button)findViewById(R.id.corky3);
        // Register the onClick listener with the implementation above
        button.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        // do something when the button is clicked
        // Yes we will handle click here but which button clicked??? We don't know

        // So we will make
        switch (v.getId() /*to get clicked view id**/) {
            case R.id.corky:

                // do something when the corky is clicked

                break;
            case R.id.corky2:

                // do something when the corky2 is clicked

                break;
            case R.id.corky3:

                // do something when the corky3 is clicked

                break;
            default:
                break;
        }
    }
}

Finally there is no real differences here Just "Way better than the other"


The logic is simple. setOnClickListener belongs to step 2.

  1. You create the button
  2. You create an instance of OnClickListener* like it's done in that example and override the onClick-method.
  3. You assign that OnClickListener to that button using btn.setOnClickListener(myOnClickListener); in your fragments/activities onCreate-method.
  4. When the user clicks the button, the onClick function of the assigned OnClickListener is called.

*If you import android.view.View; you use View.OnClickListener. If you import android.view.View.*; or import android.view.View.OnClickListener; you use OnClickListener as far as I get it.

Another way is to let you activity/fragment inherit from OnClickListener. This way you assign your fragment/activity as the listener for your button and implement onClick as a member-function.


Please note that for the sake of simplicity I have made reference to only the first code snippet i.e.,

// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    }
};

protected void onCreate(Bundle savedValues) {
    ...
    // Capture our button from layout
    Button button = (Button)findViewById(R.id.corky);
    // Register the onClick listener with the implementation above
    button.setOnClickListener(mCorkyListener);
    ...
}

setOnClickListener(View.OnClickListener l) is a public method of View class. Button class extends the View class and can therefore call setOnClickListener(View.OnClickListener l) method.

setOnClickListener registers a callback to be invoked when the view (button in your case) is clicked. This answers should answer your first two questions:

1. Where does setOnClickListener fit in the above logic?

Ans. It registers a callback when the button is clicked. (Explained in detail in the next paragraph).

2. Which one actually listens to the button click?

Ans. setOnClickListener method is the one that actually listens to the button click.

When I say it registers a callback to be invoked, what I mean is it will run the View.OnClickListener l that is the input parameter for the method. In your case, it will be mCorkyListener mentioned in button.setOnClickListener(mCorkyListener); which will then execute the method onClick(View v) mentioned within

// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    }
};

Moving on further, OnClickListener is an Interface definition for a callback to be invoked when a view (button in your case) is clicked. Simply saying, when you click that button, the methods within mCorkyListener (because it is an implementation of OnClickListener) are executed. But, OnClickListener has just one method which is OnClick(View v). Therefore, whatever action that needs to be performed on clicking the button must be coded within this method.

Now that you know what setOnClickListener and OnClickListener mean, I'm sure you'll be able to differentiate between the two yourself. The third term View.OnClickListener is actually OnClickListener itself. The only reason you have View.preceding it is because of the difference in the import statment in the beginning of the program. If you have only import android.view.View; as the import statement you will have to use View.OnClickListener. If you mention either of these import statements: import android.view.View.*; or import android.view.View.OnClickListener; you can skip the View. and simply use OnClickListener.