I have a layout which contains some views. I want to set some actions when a user clicks anywhere on the layout, so I have set an OnClickListener for the layout which works as it should. But how can I know which view was clicked? I want to assign different actions depending on the view which was clicked; or maybe no view was clicked and it was only the layout itself. So the problem is if I set OnClickListener for one of the views, both OnCLickListeners related to the layout and the view will get activated, but I want only the view action. Thanks in advance.
-
post the code of the method and xml – Rod_Algonquin Aug 06 '14 at 07:56
-
Could you explain a little more in detail? Are those views always the same ones or do you add them dynamically? Do you know you can also add `OnClickListener`s to each view? – Sergi Juanola Aug 06 '14 at 07:59
-
@Korcholis Views always are the same.I know about setOclickListener for the views, but how can I discover which one has clicked?I hace edited my question for you – Babak-Na Aug 06 '14 at 08:05
-
You can generate toast and check it in onClick(). – Aman Singh Aug 06 '14 at 08:06
-
In that case, use the way others suggest. I find interesting the one from @user2959120, as he also shows you how to assign the class itself as listener – Sergi Juanola Aug 06 '14 at 08:10
-
I could not find out how can I assign a class OnCLickListener.If I set onClick method for the fragment or activity class the problem is solved. – Babak-Na Aug 06 '14 at 08:33
-
Yes yes, when I wrote class I meant Activity or Fragment. – Sergi Juanola Aug 06 '14 at 09:55
7 Answers
Other answers are quite abstract and some are incorrect. You can't Override onClick method for an Activity as it doesn't have one (unless of course you implement an OnClickListener).
Furthermore, if you set the listener for the layout the View
argument received by the onClick method will always be the layout.
You can either create your own custom layout that intercepts the clicks and check if you clicked on a view, or you can set listeners for all the views.
A somewhat cleaner solution is using a single listener and checking if it's a view that was clicked.
private final String TAG = "MainActivity";
List<View> views = new ArrayList<View>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
TextView tv1 = (TextView) findViewById(R.id.tv1);
TextView tv2 = (TextView) findViewById(R.id.tv2);
TextView tv3 = (TextView) findViewById(R.id.tv3);
views.add(tv1);
views.add(tv2);
views.add(tv3);
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isView = false;
for (View view : views) {
if (v.equals(view)) {
isView = true;
break;
}
}
if (isView) {
Log.e(TAG, "Click on view");
} else {
Log.e(TAG, "Click on layout");
}
}
};
tv1.setOnClickListener(clickListener);
tv2.setOnClickListener(clickListener);
tv3.setOnClickListener(clickListener);
rLayout.setOnClickListener(clickListener);
}
If you want different actions for different views, just create a listener for each of them.

- 43,548
- 10
- 88
- 116
For example Layout has two views View1 and View2. I assume that you have already inflated them. So you have to set OnClickListiner for each of them
Layout.setOnClickListener(this);
View1.setOnClickListener(this);
View2.setOnClickListener(this);
Then you have to override method:
public void onClick(View v)
{
switch(v.getId())
{
case R.id.id_for_layout:
// do what you want when user click layout
break;
case R.id.id_for_first_view:
// do what you want when user click first view
break;
case R.id.id_for_second_view:
// do what you want when user click second view
break;
}
}

- 9,562
- 7
- 42
- 55
-
Where did you override the onClick method?I suppose it should be in activity or fragment class, but it does not work. – Babak-Na Aug 06 '14 at 08:27
-
@Babak-Na in same activity or fragment class. Take care to do that outside of onCreate method. – Mladen Rakonjac Aug 06 '14 at 09:19
There is View v parameter in onClickListner(View v) method :
@Override
protected void onCreate(Bundle savedInstanceState) {
LinearLayout layout=(LinearLayout)findViewById(R.id.linearLayout);
layout.setOnclickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.linearLayout){
//your logic
}
}

- 21
- 6
-
Maybe I didnt explain good enough.I want to run action A if a view has clicked and action B if the layout has clicked in free space, I mean no view has clicked for action B. – Babak-Na Aug 06 '14 at 08:09
-
your solution seems to solve the problem, but I cant find onCLick method for activity or fragment class.How can I override this method for the activity or fragment? – Babak-Na Aug 06 '14 at 08:19
-
@Dilavar this will set the onClick only for the layout, not layout and the views separately. – Babak-Na Aug 06 '14 at 08:46
-
then set view.onClickListener(this); like btn.setOnclickListner(this) – Jay Agravat Aug 06 '14 at 08:49
Remember that the method OnClick have one parameter that indicates which View is clicked!
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn1:
// first button
break;
case R.id.btn2:
// second button
break;
}
}

- 609
- 8
- 17
Assign the id to each of your views by android:id="@+id/v1" then in
onClick(View v)
check for the view like
if(v == findViewById(R.id.v1))
{
// v1 specific action
}
else if(v == findViewById(R.id.v2))
{
// v2 specific action
}

- 17
- 6
-
you should use switch statement for this..it could be more easier to implement – Pragnesh Ghoda シ Aug 06 '14 at 08:09
-
@Prag'sシ You can use both switch as well as if else ladder. and switch is better only if you have many cases. – Gaurav Gupta Aug 06 '14 at 08:20
-
yes but you are working with multiple ID if..elseif..else could be more complex to implement.. – Pragnesh Ghoda シ Aug 06 '14 at 08:22
-
-
just in simple line you have to find ID every time with `if(v == findViewById(R.id.v1))` and in `switch(v.getItemId())` can do the work.. – Pragnesh Ghoda シ Aug 06 '14 at 10:54
-
@Prag'sシ Here in switch also you have to find the id in each case by calling as R.id.desiredView. – Gaurav Gupta Aug 06 '14 at 10:59
Ok, it's easy.
You have to add an OnClickListener to each view (button, textView and so on), and to the whole layout as well.
In this case, the onClickListeners that will be launched if you click are the view's onClickListener and the layout's onClickListener.
So no need for a whole bunch of classes.
One will be enough if you try this (do actions depending on the id and don't forget the layout ;) ):
public void onClick(View v) {
switch(v.getId()) {
case R.id.layout:
layout actions here
break;
case R.id.textview:
textview actions here
break;
this onClickListener is for all of your views ;)

- 158
- 1
- 2
- 12
for anyone interested you can also log the currently clicked view:
getActivity()
.getWindow()
.getDecorView()
.findViewById(android.R.id.content)
.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.v("[onClick]", v.getClass().getCanonicalName());
}
return false;
});

- 173
- 8