setEnabled()和setClickable()有什么区别?

89

到目前为止,当我想阻止用户按下按钮时,我会设置button.setClickable(false); 通常还会将文本更改为某种灰色(以让用户知道按钮已被禁用)。今天我偶然发现了setEnabled()属性。

所以我去看文档查看方法的说明如下:

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

这到底是什么意思?启用状态/可点击状态和禁用状态/不可点击状态之间有什么区别?请问有人能解释一下我之前使用 clickable 属性和使用 setEnabled() 属性所做的事情之间的区别吗?应该在什么情况下使用它们?我在 Stack Overflow 上搜索了但没有找到任何相关的内容。


5
我猜setEnabled(false)会让一个View既不能被点击也不能被聚焦,这意味着它完全被锁定。对于Button,使用setEnabled(false)是首选方式,因为它使Button在视觉上变成“禁用”状态。 - Droidman
你是指:“因为它使按钮在视觉上变为“禁用”状态”这句话的意思是什么?它如何在视觉上进行更改?如果我使用自定义选择器会怎样? - Emil Adz
不确定自定义选择器,尚未测试过。但是对于标准按钮,它会变成半透明的,因此您无需手动处理。 - Droidman
7个回答

89

这是什么意思?

引用维基百科 GUI 元件页面

在应用程序中,小部件可能在某个时间点处于启用或禁用状态。启用的小部件有响应事件的能力,如按键或鼠标操作。不能响应此类事件的小部件被认为是禁用的。禁用小部件的外观通常与启用的小部件不同;禁用的小部件可能以较浅的颜色绘制,或以某种方式在视觉上被遮挡。参见右侧的图像。

这个概念已经存在几十年了,并且可以在大多数 GUI 框架中找到。

启用状态/可点击状态和禁用状态/不可点击状态之间有什么区别?

在 Android 中,一个不可点击的小部件将不会响应单击事件。禁用的小部件不仅不能被点击,而且还在视觉上指示它是被禁用的。

你所说的“因为它使按钮在视觉上"禁用"是什么意思?它如何在视觉上改变?

使一个 Button 看起来和响应像一个 Button 的是其背景,这是一个 StateListDrawable。有一种特定的图像用于禁用状态。


@Maver1ck:Button StateListDrawable 绝对有一个禁用状态:https://github.com/android/platform_frameworks_base/blob/master/core/res/res/drawable/btn_default.xml。虽然我不知道是否还有其他由 Button 类应用的效果。 - CommonsWare
所以基本上如果我使用自定义选择器?如果我想在特定按钮上使用setEnable()方法(并获得有关此更改的反馈),我应该指定某个可绘制对象吗? - Emil Adz
2
@EmilAdz:如果您更改文本颜色或更改按钮背景,则需要在ColorStateListStateListDrawable中为禁用状态添加适当的条目。当调用setEnabled(false)或在布局中使用android:enabled="false"时,将使用该条目。 - CommonsWare
@EmilAdz:很高兴你觉得这个有用。为了澄清我之前的评论,只有当你实际使用 setEnabled(false) 时,才需要在你的 ColorStateList 和/或 StateListDrawable 中拥有禁用状态。这是你可能会在开发早期跳过的事情,然后根据需要添加,而不是在你第一次设置自定义文本颜色或 Button 背景时总是要处理它。 - CommonsWare
@CommonsWare:“ColorStateList和/或StateListDrawable” - 我可以同时使用两者来设置同一个按钮吗?那么ColorStateList将用于字体颜色吗?“如果您实际上正在使用setEnabled(false)” - 我从未使用过此方法,因此如果在选择器中没有设置适当的可绘制对象,则意味着我将无法收到所需的反馈或应用程序由于不存在资源而崩溃? - Emil Adz
显示剩余4条评论

8

一个很大的区别是关于重叠视图的。如果一个视图的clickable属性为true并且enabled属性为false,则不允许你点击它后面的视图。但是,如果一个视图的clickable属性为false,则允许你点击它后面的视图。


8
基本上,enabled=false 不会响应任何响应,而 clickable=false 在运行时仍然会响应,相信我,我刚试过了。

2
正如Dilip所说,如果在运行时设置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();
  }
});

1

视图还可以响应外部键盘、方向键(遥控器/游戏控制器)和辅助设备(切换, 屏幕阅读器)。


0
上面列出了区别,但有一个提示。在 setOnClickListener() 之后使用 setClickable()。因为这样:
public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

0

setClickable public void setClickable (boolean clickable)

该方法用于启用或禁用特定视图的点击事件。当一个视图是可点击的时,每次点击它都会改变其状态为“按下”。如果该视图的此属性被禁用,则它不会改变其状态。

setEnabled public void setEnabled (boolean enabled)

该方法用于设置视图的启用状态。如果要启用特定视图,则在参数中传递true,否则传递false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接