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.

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top