setEnabled() vs setClickable(), what is the difference?
Asked Answered
P

7

89

Until now, when I wanted to stop the user from pressing the button, I would set the button.setClickable(false); and usually change the text to some kind of grey colour (to let the user know that the button is disabled). Today I stumbled upon the setEnabled() property.

So I went to the documentation to see the method's explanation below:

setEnabled(boolean enabled)
   Set the enabled state of this view.

What does this even mean? What is the difference between enable state/clickable state and disabled state/not clickable state? Could someone please explain what is the difference between doing what I was doing previously, using the clickable property and using the setEnabled() property? What should be used when? I searched Stack Overflow but could not find anything related.

Pourpoint answered 25/3, 2013 at 13:11 Comment(3)
I would guess that setEnabled (false) makes a View non-clickable AND non-focusable which means it gets completely locked. Also, setEnabled(false) is a preferred way in case of a Button since it makes the Button visually "disabled"Orizaba
what do you mean by: "..since it makes the Button visually "disabled"? how does it changes it visually? and what if I use a custom selector?Pourpoint
not sure about a custom selector, have not tested it. But in case of a standard Button, it gets semi-transparent so you don't need to do it by handOrizaba
C
89

What the hell is that mean?

Quoting the Wikipedia page for "GUI widget":

In the context of an application, a widget may be enabled or disabled at a given point in time. An enabled widget has the capacity to respond to events, such as keystrokes or mouse actions. A widget that cannot respond to such events is considered disabled. The appearance of disabled widget is typically different from an enabled widget; the disabled widget may be drawn in a lighter color, or may be visually obscured in some way. See the image to the right for an example.

This concept has been around for a couple of decades and can be found in most GUI frameworks.

what is the difference between enable state/clickable state and disabled state/ not clickable state?

In Android, a widget that is not clickable will not respond to click events. A disabled widget not only is not clickable, but it also visually indicates that it is disabled.

what do you mean by: "..since it makes the Button visually "disabled"? how does it changes it visually?

What makes a Button look and respond like a Button is its background, which is a StateListDrawable. There is a specific image used for the disabled state.

Comb answered 25/3, 2013 at 13:46 Comment(9)
@Maver1ck: The Button StateListDrawable definitely has a disabled state: github.com/android/platform_frameworks_base/blob/master/core/… It's possible that there are other effects applied by the Button class, though I am not aware of any.Comb
I just made a small test and it seems like for Buttons, the text color is changed as well. It gets gray when I set the button's enabled to false.Benjy
so basically if I use a custom selector? I should specify a certain drawable if I would want to use the setEnable() method on this specific button (and to get a feedback on this change)?Pourpoint
@FD_: Ah, yes, that's TextView disabled behavior, which Button inherits. Text colors are often ColorStateList objects, which also can have enabled vs. disabled states. Sorry, I forgot about that.Comb
@EmilAdz: If you change the text color, or you change the button background, you will want to have an appropriate entry in the ColorStateList or StateListDrawable for a disabled state. That entry will be used when setEnabled(false) is called, or android:enabled="false" is used in a layout.Comb
@EmilAdz: I am glad that you found this useful. To clarify my previous comment, you only need to have disabled states in your ColorStateList and/or StateListDrawable if you are actually using setEnabled(false). This is the sort of thing you might skip early in development, then add in as needed, rather that always addressing it when you first set up the custom text colors or Button backgrounds.Comb
@CommonsWare: "ColorStateList and/or StateListDrawable" - can I use both for same button? then the ColorStateList would be used for the font color?, "if you are actually using setEnabled(false)" - I never used this method, So if don't have an appropriate drawable set in the selector it means that I'm not going to receive the desired feedback or that the app is going to crash due to not existing resource?Pourpoint
@EmilAdz: "can I use both for same button? then the ColorStateList would be used for the font color?" -- yes, though if you have not changed the font color already, the standard one has a disabled state that may suffice for your needs. "it means that I'm not going to receive the desired feedback" -- AFAIK, this is what will occur.Comb
something else to note is with Espresso testing, the view may be disabled but the clickable property and hence the isClickable() matcher can return true. If onClick is not fired then clickable should not be true! Because of this strange mismatch I prefer to control the clickable property directly rather than enabled. It's simple to control clickable and alpha (to give disabled appearance) with databinding.Ramsay
P
8

So basically an enabled false doesn't respond to any response and an clickable false still response when set at runtime and trust me I just tried it.

Promptbook answered 3/8, 2016 at 10:29 Comment(0)
S
8

A big difference I don't see mentioned elsewhere is with overlapping Views. A View with clickable=true and enabled=false won't allow you to press a View behind it. But a View with clickable=false will allow you to press a View behind it.

Stamey answered 1/2, 2019 at 3:30 Comment(0)
E
2

As Dilip said, setClickable does not works if set at runtime. Here is a trick to make it working:

ToggleButton toggle = ...
toggle.setOnTouchListener(new ToggleButton.OnTouchListener() {

  @Override
  public boolean onTouch(View v, MotionEvent event) {
     // If true is returned, the event is eated by the TouchListener
     return !v.isClickable();
  }
});
Eirena answered 16/8, 2016 at 13:27 Comment(0)
F
1

Views can also respond to external keyboards, directional pads (remote/gaming controllers), and assistive devices (switch, screen readers).

Frontolysis answered 17/11, 2016 at 17:28 Comment(0)
P
0

The differences is listed above, but there is a tip. use setClickable() after setOnClickListener(). Because of this:

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}
Piefer answered 15/7, 2018 at 6:35 Comment(0)
N
0

setClickable public void setClickable (boolean clickable)

It enables or disables click events for the particular view. When a view is clickable it will change its state to "pressed" on every click. if this property of view is disabled then it will not change its state.

setEnabled public void setEnabled (boolean enabled)

It set the enabled state of this view .If the particular view is set to be enabled then pass true in the parameter else pass false

Narrative answered 20/8, 2018 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.