setEnabled() и setClickable(), в чем разница?

До сих пор, когда я хотел, чтобы пользователь не нажимал кнопку, я устанавливал button.setClickable(false); и обычно менял текст на какой-то серый цвет (чтобы пользователь знал, что кнопка отключена). Сегодня я наткнулся на свойство setEnabled().

Поэтому я обратился к документации, чтобы увидеть объяснение метода ниже:

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

Что это вообще значит? В чем разница между включенным состоянием/состоянием, доступным для нажатия, и отключенным состоянием/состоянием, не доступным для щелчка? Может кто-нибудь объяснить, в чем разница между выполнением того, что я делал ранее, использованием свойства clickable и использованием свойства setEnabled()? Что следует использовать, когда? Я искал переполнение стека, но не смог найти ничего похожего.


person Emil Adz    schedule 25.03.2013    source источник
comment
Я предполагаю, что setEnabled (false) делает представление неактивным и нефокусируемым, что означает, что оно полностью заблокировано. Кроме того, setEnabled(false) является предпочтительным способом в случае кнопки, поскольку она делает кнопку визуально отключенной.   -  person Droidman    schedule 25.03.2013
comment
что вы подразумеваете под: ... так как это делает кнопку визуально отключенной? как это меняет его визуально? а что, если я использую пользовательский селектор?   -  person Emil Adz    schedule 25.03.2013
comment
не уверен насчет пользовательского селектора, не проверял его. Но в случае стандартной кнопки она становится полупрозрачной, поэтому вам не нужно делать это вручную.   -  person Droidman    schedule 25.03.2013


Ответы (7)


Что, черт возьми, это значит?

Цитируя страницу Википедии для "GUI widget":

В контексте приложения виджет может быть включен или отключен в определенный момент времени. Включенный виджет может реагировать на события, такие как нажатия клавиш или действия мыши. Виджет, который не может реагировать на такие события, считается отключенным. Внешний вид отключенного виджета обычно отличается от включенного виджета; отключенный виджет может быть нарисован более светлым цветом или каким-то образом визуально скрыт. См. изображение справа для примера.

Эта концепция существует уже пару десятилетий и может быть найдена в большинстве графических интерфейсов.

в чем разница между включенным состоянием/состоянием кликабельности и отключенным состоянием/неактивным состоянием?

В Android виджет, на который нельзя щелкнуть, не будет реагировать на события щелчка. Отключенный виджет не только не кликабельный, но и визуально указывает на то, что он отключен.

что вы подразумеваете под: «... так как это делает кнопку визуально «отключенной»? как она визуально меняет ее?

Что заставляет Button выглядеть и реагировать как Button, так это его фон, который является StateListDrawable. Для отключенного состояния используется определенное изображение.

person CommonsWare    schedule 25.03.2013
comment
@Maver1ck: Button StateListDrawable определенно находится в отключенном состоянии: github.com/android/platform_frameworks_base/blob/master/core/ Возможно, существуют и другие эффекты, применяемые классом Button, хотя я о них не знаю. - person CommonsWare; 25.03.2013
comment
Я только что сделал небольшой тест, и кажется, что для кнопок цвет текста также изменен. Он становится серым, когда я устанавливаю для кнопки значение false. - person FD_; 25.03.2013
comment
так в основном, если я использую пользовательский селектор? Я должен указать определенный рисунок, если я хочу использовать метод setEnable() для этой конкретной кнопки (и получить отзыв об этом изменении)? - person Emil Adz; 25.03.2013
comment
@FD_: Ах, да, это TextView отключенное поведение, которое наследует Button. Цвета текста часто являются ColorStateList объектами, которые также могут иметь включенное или отключенное состояние. Извините, я забыл об этом. - person CommonsWare; 25.03.2013
comment
@EmilAdz: если вы измените цвет текста или фон кнопки, вам понадобится соответствующая запись в ColorStateList или StateListDrawable для отключенного состояния. Эта запись будет использоваться при вызове setEnabled(false) или при использовании android:enabled="false" в макете. - person CommonsWare; 25.03.2013
comment
@EmilAdz: я рад, что вы нашли это полезным. Чтобы уточнить мой предыдущий комментарий, вам нужно только отключить состояния в ваших ColorStateList и/или StateListDrawable, если вы на самом деле используете setEnabled(false). Это то, что вы можете пропустить в начале разработки, а затем добавить по мере необходимости, вместо того, чтобы всегда обращаться к этому при первой настройке пользовательских цветов текста или Button фона. - person CommonsWare; 25.03.2013
comment
@CommonsWare: ColorStateList и/или StateListDrawable — могу ли я использовать оба для одной и той же кнопки? тогда ColorStateList будет использоваться для цвета шрифта?, если вы на самом деле используете setEnabled (false) - я никогда не использовал этот метод, поэтому, если в селекторе нет соответствующего набора для рисования, это означает, что я не собираюсь получить желаемый отзыв или что приложение вылетит из-за отсутствия ресурса? - person Emil Adz; 25.03.2013
comment
@EmilAdz: могу ли я использовать оба для одной и той же кнопки? тогда ColorStateList будет использоваться для цвета шрифта? -- да, хотя, если вы еще не меняли цвет шрифта, стандартный имеет отключенное состояние, которого может быть достаточно для ваших нужд. это означает, что я не получу желаемой обратной связи — на мой взгляд, именно это и произойдет. - person CommonsWare; 25.03.2013
comment
кое-что еще, что следует отметить, это тестирование эспрессо, представление может быть отключено, но свойство clickable и, следовательно, сопоставитель isClickable() может возвращать true. Если onClick не срабатывает, то clickable не должно быть правдой! Из-за этого странного несоответствия я предпочитаю управлять кликабельным свойством напрямую, а не включать его. С помощью привязки данных легко управлять кликабельностью и альфа-каналом (чтобы придать отключенный внешний вид). - person hmac; 16.04.2020

Таким образом, в основном включенный false не отвечает ни на какой ответ, а кликабельный ложный неподвижный ответ, когда он установлен во время выполнения, и поверьте мне, я только что попробовал.

person Dilip Poudel    schedule 03.08.2016

Большая разница, о которой я нигде не упоминал, связана с перекрывающимися представлениями. Представление с clickable=true и enabled=false не позволит вам нажать на представление за ним. Но View с clickable=false позволит вам нажать View за ним.

person Trevor    schedule 01.02.2019

Как сказал Дилип, setClickable не работает, если он установлен во время выполнения. Вот трюк, чтобы заставить его работать:

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();
  }
});
person Thibault Cuvillie    schedule 16.08.2016

Представления также могут реагировать на внешние клавиатуры, панели управления (удаленные/игровые контроллеры) и вспомогательные устройства (переключатель, программы чтения с экрана) .

person Renato    schedule 17.11.2016

Отличия перечислены выше, но есть подсказка. используйте setClickable() после setOnClickListener(). Из-за этого:

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}
person Aloys_寒风    schedule 15.07.2018

setClickable public void setClickable (логическое значение, кликабельное)

Он включает или отключает события щелчка для определенного представления. Когда представление кликабельно, оно меняет свое состояние на «нажатое» при каждом щелчке. если это свойство представления отключено, то оно не изменит своего состояния.

setEnabled public void setEnabled (логическое значение включено)

Он устанавливает включенное состояние этого представления. Если конкретное представление включено, передайте true в параметре, иначе передайте false

person Muhammad Abdullah    schedule 20.08.2018