When should one use android:clickable?
Question
When should we use android:clickable
in XML? Should we ever?
Is there any difference between such XML declaration and in-code declaration myButton.setOnClickListener
? I have read the documentation, but I could not find out when and why should I ever use this attribute.
PS. I was implementing an ad SDK and found that their developers were using android:clickable
with WebView
and I was intrigued why did they use it.
Solution
As the documentation states, and as far as I know :
clickable
- Defines whether this view reacts to click events. Must be a boolean value, either "true" or "false".
So for example if you just declare a Webview
or View
in your layout.xml
and try to set an OnClickListener
on this views the OnClick
event won't be fired unless you specify the attribute :
android:clickable=true
OTHER TIPS
clickable
seems to be useful when you need a view to consume clicks so that they do not go to views beneath the top view.
For example, I have a FrameLayout
that I display over an underlying RelativeLayout
at certain times. When the user would click on an underlying EditText
the focus would shift to that EditText
. Really annoying when the FrameLayout
was still being shown. Now the user doesn't know why a keyboard just popped up or where they are typing.
When I set clickable="true"
in the FrameLayout
, users could no longer accidentally click underlying EditText
fields.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
...>
<EditText>
<EditText>
<EditText>
<!-- FrameLayout with grayed-out background. -->
<FrameLayout
android:id="@+id/sometimes_visible_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80808080"
android:clickable="true"
android:visibility="gone"
android:focusable="true"
...>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
...>
<View>
<View>
</LinearLayout>
</FrameLayout>
</RelativeLayout>
When you are setting view.setOnClickListener
on any View
,
eg: myButton.setOnClickListener(new OnClickListener)
by default it is considered
as clickable="true"
.
So you would not need to mention that in the XML file like
android:clickable="true"
. The onClick()
event will be fired without using
android:clickable="true"
.
I've experienced a situation, where I had made an activity swipeable (swipe left/right or right/left to move forward/backwards). In some screens there were places that was only filled out with a LinearLayout. There was no OnClickListener
for the layout (it wasn't needed) causing the swipe action not to be registered when performed on the LinearLayout
. Setting the android:clickable="true"
solved the problem.
To answer your questions and as the above shows, there are situations in which using the clickable
-attribute can be usefull.
I don't believe you can say that setting an OnClickListener
is the same as setting the clickable
-attribute, but setting the OnClickListener
certainly makes the View
clickable, making the clickable
-attribute useless (in that particular situation).
I don't know why did they use in that case, but, I had to use it when I created a class, which was extending linearLayout.
I created my own "control", and I wanted it clickable, so I had to use it.
This is one scenario when you will use it
FYI; When you use the android:onClick=""
attribute or call setOnClickListener(...)
programmatically, the View class sets the clickable
flag to true
.
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* @param l The callback that will run
*
* @see #setClickable(boolean)
*/
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
As to when you should set the clickable flag yourself, I think mostly when you want a View to not be cickable, e.g. to stop repeated calls while some data is loading, etc.